hdu 1226 超级密码(bfs+余数判重)
题意:略过
分析:用m个数字组成一个能够被n整除的c进制数的最小值,实际上本题的关键就在于这个最小值上。
首先确定我们的思路是从小到大寻找。先查看一位数,即查看着m个数字是否能被n整除;若不能,就查看任意可能的两位数组合...可是如此一来,预算量太大。于是我们考虑是否存在冗余量。
已知A,B两个数(A<B),A%n==x,B%n==x,我们称其为同余,那么以它们为基础的相同变换(从一位数到两位数):A*c+C,B*c+C,这两个数同样同余,(A*c+C)%n==((A*c)%n+C%n)%n==(((A%n)*c)%n+C%n)%n==(((B%n)*c)%n+C%n)%n==(B*c+C)%n。所以,若我们能够在由 B 为基础扩展出的数字中找到一个能被 n 整除的值,那经过相同的变换,由 A 扩展出的数字一定也能被 n 整除,并且一定更小。
根据以上推论,我们知道一旦我们发现一个余数为x的数字(因为是从小到大查找,该数字必然是最小值),那么之后凡是余数为x的数字都可以忽略不计。由于题目中给出的数字n<=5000,所以我们用bfs搜索,最多只需查找5000个状态,计算量大幅减少。
错误:n==0,当且仅当m个数字中含有0,答案为0;否则,无解。
注意:本题是pku 1465的延伸——由10进制数改为任意进制数,但是时限过于宽泛(也可能是数据太水了),导致用这道题的思路解题严重超时。
这是最初的思路,把每一个扩展的数字都加入队列,运算量太大。
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std; const int MAXN=;
const int N=; struct Node{
char s[MAXN];
int len;
}; int md[MAXN];
int num[N];
int n,c,m;
queue<Node>q; int Num(char ch)
{
if(ch>=''&&ch<='')
return ch-'';
return ch-'A'+;
} int qmod(Node e)
{
int cnt=;
for(int i=;i<e.len;i++)
cnt=(cnt*c+e.s[i])%n;
return cnt;
} void print(Node e)
{
for(int i=;i<e.len;i++)
if(e.s[i]>=&&e.s[i]<=)
printf("%d",e.s[i]);
else
printf("%c",e.s[i]-+'A');
printf("\n");
} int bfs()
{
memset(md,,sizeof(md));
while(!q.empty())
q.pop(); Node e;
for(int i=;i<;i++)
{
if(num[i]){
e.s[]=i;
e.len=;
int cnt=qmod(e);
if(cnt==){
print(e);
return ;
}
if(!md[cnt]){
q.push(e);
md[cnt]=;
}
}
}
while(!q.empty())
{
e=q.front();q.pop();
/*
for(int i=0;i<e.len;i++)
printf("%d",e.s[i]);
printf("\n");
*/
for(int i=;i<;i++)
{
if(num[i]){
e.s[e.len]=i;
e.len++;
if(e.len>=)
return -; int cnt=qmod(e);
if(cnt==){
print(e);
return ;
}
if(!md[cnt]){
q.push(e);
md[cnt]=;
}
e.len--;
}
}
}
//printf("??\n");
return -;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&c,&m); memset(num,,sizeof(num));
for(int i=;i<m;i++)
{
char x[];
scanf("%s",x);
num[Num(x[])]=;
}
if(n==)
if(num[])
printf("0\n");
else
printf("give me the bomb please\n");
else{
int ans=bfs();
if(ans==-)
printf("give me the bomb please\n");
}
}
return ;
}
做完pku 1465 后,又回过头来做,忘记加密码长度的限制 len<=500,狠狠的wa了一发
#include<cstdio>
#include<cmath>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std; const int MAXN=;
const int N=; struct Node{
int pre;
int r;
int d;
int len;
}; int vis[MAXN];
int num[N];
int n,c,m;
Node q[MAXN]; int Num(char ch)
{
if(''<=ch&&ch<='')
return ch-'';
return ch-'A'+;
} void print(int x)
{
if(q[x].pre==-)
return ;
print(q[x].pre);
if(q[x].d>=)
printf("%c",q[x].d-+'A');
else
printf("%d",q[x].d);
} int bfs()
{
memset(vis,,sizeof(vis));
int dl,dr;
dl=dr=;
Node u,v;
u.pre=-;
u.d=;
u.r=;
u.len=;
q[dr++]=u;
vis[]=; int ok=;
while(dl<dr)
{
u=q[dl++];
for(int i=;i<m;i++)
{
int r=u.r*c+num[i];
if(r>=n&&r%n==){
print(dl-);
if(num[i]>=)
printf("%c\n",num[i]-+'A');
else
printf("%d\n",num[i]);
return ;
}
r=r%n;
if(!vis[r]){
vis[r]=;
v.r=r;
v.d=num[i];
v.pre=dl-;
v.len=u.len+;
if(v.len>)
return -;
q[dr++]=v;
}
}
}
return -;
} int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%d%d%d",&n,&c,&m);
memset(num,-,sizeof(num));
for(int i=;i<m;i++)
{
char s[];
scanf("%s",s);
num[i]=Num(s[]);
}
sort(num,num+m); if(n==)
if(num[]==)
printf("0\n");
else
printf("give me the bomb please\n");
else{
int ans=bfs();
if(ans==-)
printf("give me the bomb please\n");
}
}
return ;
}
hdu 1226 超级密码(bfs+余数判重)的更多相关文章
- hdu.1226.超级密码(bfs)
超级密码 Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- HDU 1226 超级密码(BFS) (还需研究)
Time Limit:10000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Desc ...
- hdu 1226 bfs+余数判重+大数取余
题目: 超级密码 Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total ...
- HDU 1226 超级密码(数学 bfs)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1226 超级密码 Time Limit: 20000/10000 MS (Java/Others) ...
- poj 1465 Multiple(bfs+余数判重)
题意:给出m个数字,要求组合成能够被n整除的最小十进制数. 分析:用到了余数判重,在这里我详细的解释了.其它就没有什么了. #include<cstdio> #include<cma ...
- hdu 1226 超级密码
超级密码 Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem D ...
- HDOJ 1226 超级密码(bfs)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1226 思路分析:题目要求寻找一串长度不大于500的C进制的密码,且该密码需要为十进制数N的整数倍. & ...
- HDU 1226 超级密码 (搜素)
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1226 题意简单,本来是一道很简单的搜素题目. 但是有两个bug: 1.M个整数可能有重复的. 2.N可 ...
- hdu1664 bfs+余数判重
input n 不超过50个例子,n==0结束输入 Sample Input 7 15 16 101 0 output 最少个不同数字的n的倍数的x,若不同数字个数一样,输出最小的x Sample O ...
随机推荐
- 如何使用 Docker 部署一个基于 Play Framework 的 Scala Web 应用?
本文作者 Jacek Laskowski 拥有近20年的应用程序开发经验,现 CodiLime 的软件开发团队 Leader,曾从 IBM 取得多种资格认证.在这篇博文中,Jacek 分享了 Wars ...
- iOS16进制设置颜色
UIColor+Hex.h // // UIColor+Hex.h // 16进制颜色类别 // // Created by apple on 15-4-3. // Copyright (c) 201 ...
- HDU 1869 六度分离
六度分离 http://acm.hdu.edu.cn/showproblem.php?pid=1869 Problem Description 1967年,美国著名的社会学家斯坦利·米尔格兰姆提出了一 ...
- ActionResult 返回类型
类名 抽象类 父类 功能 ContentResult 根据内容的类型和编码,数据内容. EmptyResult 空方法. FileResult abstract 写入文件内容,具体 ...
- java基础知识回顾之javaIO类---BufferedReader和BufferedWriter
使用了装饰设计模式:此类的设计是为了提高流操作数据的效率.思想就是定义容器将数据进行临时存储,对于缓冲区对象,其实就是将这个容器进行了分装,并提供了更高效的操作方法. BufferReader: pa ...
- ios开发之AppDelegate
创建应用程序之后之后,默认有AppDelegate.h文件与AppDelegate.m文件. AppDelegate为何物? AppDelegate为整个应用的一个代理,提供程序启动.退出等类似 ...
- x64 结构体系下的内存寻址
欢迎转载,转载请注明出处:http://www.cnblogs.com/lanrenxinxin/p/4735027.html 在阅读NewBluePill源码的时候,看内存的那一块简直头疼,全是x6 ...
- Junit单元测试学习笔记一
我们在编写大型程序的时候,需要写成千上万个方法或函数,这些函数的功能可能很强大,但我们在程序中只用到该函数的一小部分功能,并且经过调试可以确定,这一小部分功能是正确的.但是,我们同时应该确保每一个函数 ...
- java中的基本数据类型存放位置
基本数据类型是放在栈中还是放在堆中,这取决于基本类型声明的位置. 一:在方法中声明的变量,即该变量是局部变量,每当程序调用方法时,系统都会为该方法建立一个方法栈,其所在方法中声明的变量就放在方法栈中, ...
- 使用HTML5实现刮刮卡效果
你玩过刮刮卡么?一不小心可以中奖的那种.今天我给大家分享一个基于HTML5技术实现的刮刮卡效果,在PC上只需按住鼠标,在手机上你只需按住指头,轻轻刮去图层就可以模拟真实的刮奖效果. 我们利用HTML5 ...