题意:略过

分析:用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. C#索引器及示例

    public class IndexSeletor<T> where T:struct { private List<T> _listObj; public IndexSele ...

  2. jquey ajax 无刷新提交form

    http://bbs.csdn.net/topics/380237868 $.ajax({ type: "POST", url:ajaxCallUrl, data:$('#your ...

  3. 【hadoop】mapreduce原理总结

    看了两天的各种博客,终于把MapReduce的原理理解了个大概.花了1个小时画了个流程图.大家看看,有不对的地方欢迎指正. 关键步骤: Map, Reduce就不多说了.记录一下我看了很久的部分: 1 ...

  4. 安装wps for linux无法启动

    我下载的是deb包,双击安装完之后,打开wps没有反应,重启了一下 计算机也不行. 改从命令行出现如下信息: /opt/kingsoft/wps-office/office6/wps: error w ...

  5. VISO下载地址

    http://pan.baidu.com/share/home?uk=4011207371#category/type=0

  6. 用eclipse创建maven项目

    Maven是基于项目对象模型(POM),也可以进行模块化开发.并且是个强大的管理工具.本经验用eclipse来创建maven项目 步骤: 1.下载并正确安装eclipse 2.在eclipse上成功安 ...

  7. 关于linux下rar文件的解压缩操作

    在linux系统下.本身没有对rar文件操作的命令,如果需要对rar格式的文件操作,我们需要安装第三方的软件rar以及unrar. 1.linux下rar管理软件下载的官方地址为:http://www ...

  8. Java7编程 高级进阶学习笔记--嵌套类

    定义: 在一个类中定义的类叫做嵌套类. 作用: 1.允许对相关类进行逻辑分组 2.增强了代码的封装性 3.使代码具有更强的可读性和维护性 使用方式: package com.cmz.baseTest; ...

  9. 重温《js权威指南》 第2-3章

    第二章 语法结构         2.1 js区分大小写,html不区分大小写         2.5 注意分号,如果没有分号,解释器会试图解析js,并在不能解析的地方加分号 第三章 值和变量     ...

  10. jQuery 实验教程

    jQuery 实验教程 jQuery 简介.语法及事件处理 jQuery 以其特有的简练的代码风格,极大得改变了 JavaScript 代码编写的方式.本教程以实例代码为基础,讲解 jQuery 的使 ...