超级密码

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3866    Accepted Submission(s): 1241

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

Hint

Hint

Huge input, scanf is recommended.

 
Author
Ignatius.L
 
Source
 
题解:强大的同余剪枝,如果某个数 a%n == b%n (a<b) 如果目标状态为 (a + c)%n == 0,而(a+c)%n = a%n + c%n = b%n + c%n ,所以搜索 a b是等价的,但是我们要的是最小的解,所以我们可以不再去找b,所以我们标记余数,这样的话可以剪掉非常多的状态,这样的话就不会超时了.
所以具体解法为排序后进行同余搜索,0要特判。
#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>
#include <stdlib.h>
#include <string>
#include <iostream>
using namespace std;
int n,c,m;
bool mod[];
char num[];
struct Node{
int mod;
string ans;
int len;
};
void bfs(){
memset(mod,,sizeof(mod));
queue<Node> q;
Node s;
for(int i=;i<=m;i++){
if(num[i]!='') {
s.ans= num[i];
if(isdigit(num[i])) s.mod = (num[i]-'')%n;
else s.mod = (num[i]-'A'+)%n;
s.len = ;
q.push(s);
}
}
while(!q.empty()){
Node now = q.front();
q.pop();
//cout<<now.ans<<endl;
if(now.len>) {
printf("give me the bomb please\n");
return;
}
if(now.mod==){
cout<<now.ans<<endl;
return ;
}
Node next;
for(int i=;i<=m;i++){
next.ans = now.ans+num[i];
if(isdigit(num[i])) next.mod = (now.mod*c+(num[i]-''))%n;
else next.mod = (now.mod*c+(num[i]-'A'+))%n;
//cout<<next.ans<<endl;
next.len=now.len+;
if(mod[next.mod]) continue;
mod[next.mod]=true;
q.push(next);
}
}
printf("give me the bomb please\n");
return;
}
int main(){
int tcase;
scanf("%d",&tcase);
while(tcase--){
scanf("%d%d",&n,&c);
scanf("%d",&m);
bool flag = false;
getchar();
for(int i=;i<m;i++){
scanf("%c ",&num[i]);
if(n==&&num[i]=='') flag = true;
}
scanf("%c",&num[m]);
if(n==&&num[m]=='') flag = true;
sort(num+,num++m);
if(n==){
if(flag){
printf("0\n");
continue;
}else{
printf("give me the bomb please\n");
continue;
}
}
bfs();
}
return ;
}

hdu 1226(同余搜索)的更多相关文章

  1. hdu 1226 bfs+余数判重+大数取余

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

  2. hdu 1664(数论+同余搜索+记录路径)

    Different Digits Time Limit: 10000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others ...

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

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

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

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

  5. HDU 4616 Game (搜索)、(树形dp)

    题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=4616 这道题目数据可能比较弱,搜索都可以AC,但是不敢写,哎…… 搜索AC代码: #include & ...

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

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

  7. hdu 1226 BFS + bfs记录路径

    http://acm.hdu.edu.cn/showproblem.php? pid=1226 为了节省空间.您可以使用vis初始化数组初始化-1. 发现BFSeasy错了地方 始一直WA在这里:就是 ...

  8. [HDU 2102] A计划(搜索题,典型dfs or bfs)

    A计划 Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submiss ...

  9. hdu 4722(记忆化搜索)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4722 思路:简单的记忆化搜索,留意一下A==0时的情况就可以了. #include<iostre ...

随机推荐

  1. POI 2018.10.22

    [POI2015]ODW 喵锟讲过.分块. N>=blo,那就暴力倍增往上跳.O(N/blo*logN) N<blo,预处理,f[i][j]表示,i往上跳,每次跳j步,到根节点为止,权值和 ...

  2. How far away ? LCA求树上两点距离

    How far away ? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  3. simpleDateFormat的 学习

    http://blog.csdn.net/qq_27093465/article/details/53034427

  4. mac命令行配置网络

    mac命令行配置网络今天终于找到了Mac OS X通过命令行修改ip的方式了,记录如下: 修改mac地址,重启后失效sudo ifconfig en0 lladdr d0:67:e5:2e:07:f1 ...

  5. LightOJ 1218 概率水题(几何分布)

    题意:给你一个n面骰子,问你投出所有面需要的次数的期望值是多少. 题解:放在过去估计秒解,结果现在自己想好久,还查了下,有人用极限证明...实际上仔细想想这种情况投出与前面不一样的概率p的倒数就是次数 ...

  6. [洛谷P3401] 洛谷树

    洛谷题目连接:洛谷树 题目背景 萌哒的Created equal小仓鼠种了一棵洛谷树! (题目背景是辣鸡小仓鼠乱写的QAQ). 题目描述 树是一个无环.联通的无向图,由n个点和n-1条边构成.树上两个 ...

  7. Linux查看进程的所有子进程和线程

    得到进程的pid: ps -ef | grep process_name | grep -v "grep" | awk '{print $2}' 查看进程的所有线程 # ps mp ...

  8. 【spoj1182/usaco-Cow Queueing, 2003 Dec-二进制编号】数位dp

    题意:定义新的排序:先按一个数中二进制中1的个数从小到大排序,如果1的个数相同则按数的大小从小到大排序.问[A,B]之间有第K大的数是哪个.-2^31<=A,B<=2^31(A,B必定同正 ...

  9. bzoj 1034 贪心

    首先如果我们想取得分最高的话,肯定尽量赢,实在赢不了的话就耗掉对方最高的,那么就有了贪心策略,先排序,我方最弱的马和敌方最弱的相比,高的话赢掉,否则耗掉敌方最高的马. 对于一场比赛,总分是一定的,所以 ...

  10. this可以通过call改变的测试