hdu 1226 超级密码bfs
来源:互联网 发布:淘宝客返利机器人 编辑:程序博客网 时间:2024/06/07 02:01
Hand In Hand
Online Acmers
Forum | Discuss
Statistical ChartsSTD Contests
VIP Contests
Virtual Contests
DIY | Web-DIY beta
Recent Contests
Mail 0(0)
Control Panel
Sign Out
超级密码
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 929 Accepted Submission(s): 302
密码是一个C进制的数,并且只能由给定的M个数字构成,同时密码是一个给定十进制整数N(0<=N<=5000)的正整数倍(如果存在多个满足条件的数,那么最小的那个就是密码),如果这样的密码存在,那么当你输入它以后门将打开,如果不存在这样的密码......那就把门炸了吧.
注意:由于宝藏的历史久远,当时的系统最多只能保存500位密码.因此如果得到的密码长度大于500也不能用来开启房门,这种情况也被认为密码不存在.
注意:在给出的M个数字中,如果存在超过10的数,我们约定用A来表示10,B来表示11,C来表示12,D来表示13,E来表示14,F来表示15.我保证输入数据都是合法的.
注意:构成密码的数字不一定全部都要用上;密码有可能非常长,不要试图用一个整型变量来保存密码;我保证密码最高位不为0(除非密码本身就是0).
322 1037 0 12 101125 163A B C
110give me the bomb pleaseCCBHuge input, scanf is recommended.HintHint
这题目仍然是增加一位数求余数......
在POJ上有一道类似题目.给一个数字,求其只由0或1组成的某个倍数..原理相同....哈哈我当时没优化...这次学乖了优化了才过......
基本原理:
r= k (mod c)則 (k*p+a)(mod c)=(r*p+a)(mod c)
形式证明.....r=k(mod c)-> k= q*c+r -> (k*p+a)=((q*c+r)*p+a)=p*q*c+p*r+a -> (k*p+a) (mod c) = (r*p+a) (mod c)
(注:由于p*q*c中含有因子c,所以取模后=0.........)
优化原理:(据说理论基础是"鸽巢原理"....个人无法明白....如果有人能解释感激不尽....)
随便说下吧....
如果某个数值序列的余数为r.....如果某个余数已经被构造过...那么后面得到的一定是与原来构造过的余数序列相同的序列...意思是..这是一个循环(周期函数?....扯远了...)..而由BFS的性质.最短的一定是最先被构造出来的..所以.....先到先得!(每一位使用什么数字都是不变的哦.....就是在同一个数值集合内...).
那么之前那些高位的数字呢?...不用管数值序列了,只看余数......既然知道余数是r,如果这个余数已经出现过.那么接下来构造的序列的余数序列 r1,r2,r3,.....一定是之前重复过的.而纠缠这些相同的还有啥么意义呢....咱们要余数为0的....
所以...终于到结论了....
只要某种余数曾经出现过.那么这种余数就不需要再出现.....这个东西表达在代码上不会太困难,因为题目已经给了数值范围<=5000.所以.....完了
顺便提示:没有优化会死的很惨烈很惨烈....
-------
关于题目的....
对于0什么时候可能出现呢?....
一个数n的倍数一定大于等于n...(题目除0了..),但是余数为0除了0之外,至少都是大于等于n....这不需要特别判定
然而当题目给的某数字为0,并且单纯一位的值存在0,才为0...否则..不存在这样的数值序列.....
为什么一个非0值 ...1,2或者其他...不能成为0的倍数呢?...不得知.....这看来还得看测试数据.....
我也搞不懂了,看了别人的代码才知道....幸亏有人分享代码哎...否则又要WA一辈子了.....
#include<stdio.h>#include<algorithm>using namespace std;#define N 100000/*只是01串那道题的强化版本而已,要求长度小于500,N<5000,明显要优化,对余数的判重。*/int c[17];int pre[N],prec[N];int que[N];int cc,n,m;int bfs(){ int i=0,j,k,t,r,vis[N]={0}; int front=0,rear=0; if(c[0]==0) { i=1; rear=1; front=1; pre[0]=-1; prec[0]=0; } if(n==0) { if(c[0]==0) return 0; return -1; } for(;rear<m;++i,++rear) { que[rear]=c[i]%n; prec[i]=c[i]; pre[i]=-1; vis[que[rear]]=1; if(que[rear]==0) return i; } while(front<rear) { r=que[front]; if(vis[r]==500) return -1; k=front++; for(j=0;j<m;++j) { t=(r*cc+c[j])%n; if(!vis[t]) { vis[t]=vis[r]+1; prec[i]=c[j]; pre[i]=k; if(t==0) return i; i++; que[rear++]=t; } } } return -1;}void solve(){ int k=bfs(); if(k==-1) { printf("give me the bomb please\n"); return ; } char str[N]; int i=0; for(;k!=-1;++i,k=pre[k]) { if(prec[k]<10) str[i]=char(prec[k]+'0'); else str[i]=char(prec[k]-10+'A'); } --i; while(i>0) printf("%c",str[i--]); printf("%c\n",str[i]);}int main(){ int i,t; char s[2]; scanf("%d",&t); while(t--) { scanf("%d%d%d",&n,&cc,&m); for(i=0;i<m;++i) { scanf("%s",s); if(s[0]<='9') c[i]=s[0]-'0'; else c[i]=s[0]-'A'+10; } sort(c,c+m); solve(); } return 0;}/**/
- hdu 1226 超级密码bfs
- HDU 1226 超级密码(BFS)
- BFS-hdu-1226-超级密码
- hdu 1226 超级密码 bfs
- hdu 1226 超级密码【BFS】
- 【hdu】1226 超级密码【bfs】
- hdu 1226 超级密码 bfs
- Hdu-1226-超级密码 [bfs]
- [HDU 1226]超级密码:BFS
- HDU 1226超级密码(数位BFS)
- hdu 1226 超级密码 bfs+取余判重
- HDU 1226 超级密码 (bfs好题)
- HDU 1226 超级密码(BFS)
- hdu-超级密码(BFS)
- HDU 1266 超级密码 bfs
- hdu 1226 超级密码 (bfs+取余判重 poj 1465加强版 )
- hdu 1226 超级密码 BFS 挺不错的题啊!
- hdu 1226 超级密码(BFS,同余剪枝)
- Win7 64 配置MinGW,以及使用Eclipse
- Building a JSON web service with Java and Axis2
- C语言实现位图(bitmap)
- 黑马程序员 java基础备忘
- ID3DXSprite
- hdu 1226 超级密码bfs
- 2499. 平方数
- Android SDK安装及常见问题解决
- mini language 学习笔记
- 杭电ACM 1201 18岁生日
- 注册google map 的密钥(API Key)
- 博客搬新家
- ubuntu 指令集
- Jquery浅谈之讲解二