您的位置:首页 > 其它

hdu - 1226 超级密码 (bfs)

2015-05-29 21:27 369 查看
http://acm.hdu.edu.cn/showproblem.php?pid=1226

难以想到怎么去bfs,还是对状态的划分不明确,知道了之后感觉还是挺简单的。

这题关键是密码可能很长,然后判断是否整除用到了一点技巧,确保不会溢出,输出的时候是用递归回溯输出。

因为同一个数可以取多次,而最终取的是数值最小的,故输入之后从小到大排序,然后从第一个数到最后一个数每次添加一遍,直到找到合适的为止.

为了便于输出用了数组模拟队列.

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
using namespace std;
struct point
{
int mod;
int digit;
int pre;
int step;
}Queue[5001],init={0,0,-1};
int n,c,m;
int num[20];
int used[5010];

void echo(int x)
{
if(Queue[x].pre==-1) return;
else echo(Queue[x].pre);
if(Queue[x].digit>=0&&Queue[x].digit<=9) printf("%c",Queue[x].digit+'0');
else printf("%c",Queue[x].digit+'A'-10);
}
void bfs()
{
memset(used,0,sizeof(used));
int front=0,rear=1;
bool flag=0;
Queue[0]=init;
while(front!=rear)
{
point e=Queue[front];
for(int i=0;i<m;i++)
{
int ans=(e.mod*c+num[i])%n;   // 计算余数是否为0
//  printf("%d %d\n",num[i],ans);
if(used[ans]||e.pre==-1&&num[i]==0||e.step>=500) continue;
used[ans]=1;
Queue[rear].pre=front;
Queue[rear].digit=num[i];
Queue[rear].mod=ans;
Queue[rear].step=e.step+1;
if(ans==0) {echo(rear);printf("\n");flag=1;break;}
rear++;
}
front++;
}
if(!flag) printf("give me the bomb please\n");
}
int main()
{
freopen("a.txt","r",stdin);
int t;
char str[20];
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&c,&m);
getchar();
for(int i=0;i<m;i++)
{
scanf("%s",str);
if(str[0]>='0'&&str[0]<='9') num[i]=str[0]-'0';
else num[i]=10+str[0]-'A';
// printf("%d\n",num[i]);
}
sort(num,num+m);
if(n==0)
{
if(num[0]==0) printf("0\n");
else printf("give me the bomb please\n");
}
else bfs();
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: