题意:略过

分析:用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+余数判重)的更多相关文章

  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+余数判重+大数取余

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

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

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

  5. poj 1465 Multiple(bfs+余数判重)

    题意:给出m个数字,要求组合成能够被n整除的最小十进制数. 分析:用到了余数判重,在这里我详细的解释了.其它就没有什么了. #include<cstdio> #include<cma ...

  6. hdu 1226 超级密码

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

  7. HDOJ 1226 超级密码(bfs)

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

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

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

  9. hdu1664 bfs+余数判重

    input n 不超过50个例子,n==0结束输入 Sample Input 7 15 16 101 0 output 最少个不同数字的n的倍数的x,若不同数字个数一样,输出最小的x Sample O ...

随机推荐

  1. POJ 3662

    Telephone Lines Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4591   Accepted: 1693 D ...

  2. 我是如何学习 Linux 的

    为何要学习 Linux? 这个问题可能困扰着很多 Linux 初学者和爱好者,其实我也说不上来为何要学习 Linux,可能最实在的理由就是—-Linux 相关工作岗位很多.在“见到” Linux 的第 ...

  3. Codeforces Round #337 (Div. 2) C. Harmony Analysis 数学

    C. Harmony Analysis   The semester is already ending, so Danil made an effort and decided to visit a ...

  4. node操作MongoDB数据库之插入

    在上一篇中我们介绍了MongoDB的安装与配置,接下来的我们来看看在node中怎样操作MongoDB数据库. 在操作数据库之前,首先应该像关系型数据库一样建个数据库把... 启动数据库 利用命令提示符 ...

  5. mysql 支持中文,防止程序乱码的方法

    1. 查看你的mysql的字符设置 mysql> show variables like 'character%'; +--------------------------+---------- ...

  6. linux下python启动第三方程序,并控制关闭

    import subprocess import os import signal p = subprocess.Popen("recordmydesktop -o /home/test/t ...

  7. 312. Burst Balloons

    题目: Given n balloons, indexed from 0 to n-1. Each balloon is painted with a number on it represented ...

  8. python流程控制语句 ifelse - 3

    #! /usr/bin/python x = input ('please inut a integer:') x = int(x) : print ('你输入了一个负数') elif x == : ...

  9. hadoop安装配置——伪分布模式

    1. 安装 这里以安装hadoop-0.20.2为例 先安装java,参考这个 去着下载hadoop 解压 2. 配置 修改环境变量 vim ~/.bashrc export HADOOP_HOME= ...

  10. Maven+Spring+Mybatis+Security+Mysql简短的框架

    一段时间想搞个框架做开发,但是网上好多代码建立的都太杂乱.有的开源的东西我感觉用不了.本人太笨,不懂怎么上传到github上,就写在博客里,留作记录.以后用的时候也方便. 1.首先让我们看一下项目结构 ...