Problem Description
Ignatius花了一个星期的时间终于找到了传说中的宝藏,宝藏被放在一个房间里,房间的门用密码锁起来了,在门旁边的墙上有一些关于密码的提示信息:

码是一个C进制的数,并且只能由给定的M个数字构成,同时密码是一个给定十进制整数N(0<=N<=5000)的正整数倍(如果存在多个满足
条件的数,那么最小的那个就是密码),如果这样的密码存在,那么当你输入它以后门将打开,如果不存在这样的密码......那就把门炸了吧.
注意:由于宝藏的历史久远,当时的系统最多只能保存500位密码.因此如果得到的密码长度大于500也不能用来开启房门,这种情况也被认为密码不存在.
 
Input

入数据的第一行是一个整数T(1<=T<=300),表示测试数据的数量.每组测试数据的第一行是两个整数N(0<=N&
lt;=5000)和C(2<=C<=16),其中N表示的是题目描述中的给定十进制整数,C是密码的进制数.测试数据的第二行是一个整数
M(1<=M<=16),它表示构成密码的数字的数量,然后是M个数字用来表示构成密码的数字.两个测试数据之间会有一个空行隔开.

注意:在给出的M个数字中,如果存在超过10的数,我们约定用A来表示10,B来表示11,C来表示12,D来表示13,E来表示14,F来表示15.我保证输入数据都是合法的.

 
Output
对于每组测试数据,如果存在要求的密码,则输出该密码,如果密码不存在,则输出"give me the bomb please".

注意:构成密码的数字不一定全部都要用上;密码有可能非常长,不要试图用一个整型变量来保存密码;我保证密码最高位不为0(除非密码本身就是0).

 
Sample Input
3
22 10
3
7 0 1
2 10
1
1
25 16
3
A B C
 
Sample output
110
give me the bomb please
CCB
 
题目分析:由于是求最小的密码,显然就应该用BFS了,其实用DFS加上剪枝(这的剪枝比BFS代码中的剪枝还要多那么一丢丢)也能跑出正确的结果,但仍然会TLE。同余剪枝:当刚出队列的状态转移到下一个时,对n的模已经出现过了,则剪去。
 
代码如下:
 AC的BFS+剪枝:
 # include<iostream>
# include<cstdio>
# include<string>
# include<queue>
# include<cstring>
# include<algorithm>
using namespace std;
struct node
{
string ans;
int val;
node(string s,int m):ans(s),val(m){}
bool operator < (const node &a) const {
if(ans.size()==a.ans.size())
return ans>a.ans;
return ans.size()>a.ans.size();
}
};
int vis[],n,m,c,num[];
int get()
{
char ch;
cin>>ch;
if(ch>=''&&ch<='')
return ch-'';
return ch-'A'+;
}
void bfs()
{
memset(vis,,sizeof(vis));
priority_queue<node>q;
for(int i=;i<m;++i){
if(num[i]==)
continue;
string s;
if(num[i]<=)
s+=num[i]+'';
else
s+=num[i]-+'A';
vis[num[i]%n]=;
q.push(node(s,num[i]%n));
}
while(!q.empty())
{
node u=q.top();
q.pop();
if(u.val==){
cout<<u.ans<<endl;
return ;
}
if(u.ans.size()>=)
continue;
for(int i=;i<m;++i){
int now=(u.val*c+num[i])%n;
if(vis[now])
continue;
string s=u.ans;
if(num[i]<=)
s+=num[i]+'';
else
s+=num[i]-+'A';
vis[now]=;
q.push(node(s,now));
}
}
printf("give me the bomb please\n");
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&c);
scanf("%d",&m);
for(int i=;i<m;++i)
num[i]=get();
sort(num,num+m);
if(n==){
if(num[]==)
printf("0\n");
else
printf("give me the bomb please\n");
continue;
}
bfs();
}
return ;
}

TLE的DFS+剪枝写法:

 # include<iostream>
# include<cstdio>
# include<string>
# include<cstring>
# include<algorithm>
using namespace std;
int vis[],n,m,c,num[],flag;
string aans;
int get()
{
char ch;
cin>>ch;
if(ch>=''&&ch<='')
return ch-'';
return ch-'A'+;
}
bool is_smaller(string s1,string s2)
{
if(s1.size()<s2.size())
return true;
if(s1.size()==s2.size()&&s1<s2)
return true;
return false;
}
void dfs(string ans,int s)
{
if(ans.size()>)
return ;
if(s==){
if(!flag){
aans=ans;
flag=;
}
else{
if(is_smaller(ans,aans))
aans=ans;
}
return ;
}
//cout<<ans<<endl;
if(flag){
if(aans.size()<ans.size())
return ;
if(aans.size()==ans.size()&&ans>aans)
return ;
}
string temp=ans;
for(int i=;i<m;++i){
int ns=(s*c+num[i])%n;
if(vis[ns])
continue;
if(num[i]<=)
ans+=num[i]+'';
else
ans+=num[i]+'A'-;
vis[ns]=;
dfs(ans,ns);
vis[ns]=;
ans=temp;
}
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&c);
scanf("%d",&m);
for(int i=;i<m;++i)
num[i]=get();
sort(num,num+m);
flag=;
memset(vis,,sizeof(vis));
for(int i=;i<m;++i){
//cout<<num[i]<<endl;
string ans;
if(num[i]==)
continue;
if(num[i]<=)
ans+=num[i]+'';
else
ans+=num[i]-+'A';
if(num[i]%n==){
aans=ans;
flag=;
break;
}
vis[num[i]%n]=;
dfs(ans,num[i]%n);
vis[num[i]%n]=;
}
if(!flag)
printf("give me the bomb please\n");
else
cout<<aans<<endl;
}
return ;
}

HDU-1226 超级密码 (BFS+剪枝)的更多相关文章

  1. hdu.1226.超级密码(bfs)

    超级密码 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  2. HDU 1226 超级密码(BFS) (还需研究)

    Time Limit:10000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Submit Status Desc ...

  3. HDU 1226 超级密码(数学 bfs)

    传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1226 超级密码 Time Limit: 20000/10000 MS (Java/Others)    ...

  4. hdu 1226 超级密码

    超级密码 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Problem D ...

  5. hdu 1226 超级密码(bfs+余数判重)

    题意:略过 分析:用m个数字组成一个能够被n整除的c进制数的最小值,实际上本题的关键就在于这个最小值上.  首先确定我们的思路是从小到大寻找.先查看一位数,即查看着m个数字是否能被n整除:若不能,就查 ...

  6. HDOJ 1226 超级密码(bfs)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1226 思路分析:题目要求寻找一串长度不大于500的C进制的密码,且该密码需要为十进制数N的整数倍. & ...

  7. HDU 1226 超级密码 (搜素)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1226 题意简单,本来是一道很简单的搜素题目. 但是有两个bug: 1.M个整数可能有重复的. 2.N可 ...

  8. hdu1226超级密码 bfs

    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1226/ 题目大意是:寻找一个五百位之内的C进制密码,该密码是N的正整数倍,而且只能用给定的数构成密码,求这样的密 ...

  9. HDOJ 1226 超级密码

    超级密码 Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Subm ...

  10. 超级密码(bfs)

    超级密码 Time Limit : 20000/10000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submis ...

随机推荐

  1. C/C++之全局、static对象/变量的初始化问题

    关于全局.static对象/变量的初始化问题 1. 全局变量.static变量的初始化时机:main()函数执行之前(或者说main中第一个用户语句执行之前). 2. 初始化顺序. 1)全局对象.外部 ...

  2. oracle中验证身份证是否合法的函数脚本

    --创建函数 入参是身份证   返回1 合法 0不合法 CREATE OR REPLACE FUNCTION fn_checkidcard (p_idcard IN VARCHAR2) RETURN ...

  3. Linux Touch命令的8种使用技巧

    Linux touch命令不仅可以用于在Linux上创建空文件. 您可以使用它来更改现有文件的时间戳,包括其访问权限和修改时间. 本文介绍了8种可以通过Linux终端使用touch命令的方案. 我们在 ...

  4. DNS正反向区域解析(二)

    域名查询工具 Nslookup命令 >server 202.106.0.20 #指定DNS服务器 >set q=A #指定要查询的类型(A,PTR,MX,CNAME,NS) >www ...

  5. SNMP学习笔记之SNMPv3的配置和认证以及TroubleShooting

    0x00 增加snmp v3用户 增加用户的时候,必须要停止SNMP服务. # service snmpd stop # net-snmp-config --create-snmpv3-user -r ...

  6. python监控端口脚本[jkport1.0.py]

    此脚本根据端口判断进程是否存活, 如果有指定的端口就证明进程是没问题的, 如果检测不到端口就是说业务进程已经挂掉了, 此时自动重启程序, 不多说下面请看脚本 创建脚本 我这里模拟的是nginx, 监控 ...

  7. 小测(noip2005的两道题) 2017.3.3

    过河 题目描述 Description 在河上有一座独木桥,一只青蛙想沿着独木桥从河的一侧跳到另一侧.在桥上有一些石子,青蛙很讨厌踩在这些石子上.由于桥的长度和青蛙一次跳过的距离都是正整数,我们可以把 ...

  8. compile vi from source code

    1.install ncurses library (vi  depend on ncurses library) ./configure --prefix=/usr --with-termlib m ...

  9. vuejs全局api概念

    什么是全局API? 全局API并不在构造器里,而是先声明全局变量或者直接在Vue上定义一些新功能,Vue内置了一些全局API,比如我们今天要学习的指令Vue.directive.说的简单些就是,在构造 ...

  10. java 如果仅输出一位和要输出多位格式的输出问题,利用boolean值.

    package com.ykmimi.testtest; /** * 第七周第二题,来自网络 */ import java.util.Scanner; public class NumberPerfe ...