HDU-1226-超级密码-队列+广搜+大数取模
Ignatius花了一个星期的时间终于找到了传说中的宝藏,宝藏被放在一个房间里,房间的门用密码锁起来了,在门旁边的墙上有一些关于密码的提示信息:
密码是一个C进制的数,并且只能由给定的M个数字构成,同时密码是一个给定十进制整数N(0<=N<=5000)的正整数倍(如果存在多个满足条件的数,那么最小的那个就是密码),如果这样的密码存在,那么当你输入它以后门将打开,如果不存在这样的密码......那就把门炸了吧.
注意:由于宝藏的历史久远,当时的系统最多只能保存500位密码.因此如果得到的密码长度大于500也不能用来开启房门,这种情况也被认为密码不存在.
Input
输入数据的第一行是一个整数T(1<=T<=300),表示测试数据的数量.每组测试数据的第一行是两个整数N(0<=N<=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
Huge input, scanf is recommended.
思路:
先将题目给的m个字符进行标记,先进行第一轮循环,看看是否有个位数直接是n的倍数(0除外,因为题目规定最高位不能为0)再开始进队列,进行广搜。
需要注意的细节:
1、输入用%s输入单个字符,因为存在空格,%s不接收空格,%c会接收空格
2、大数取模公式:(a+b)%m=(a%m+b%m)%m
例如:175%6 =(100+70+5)%6 =100%6+70%6+5%6 =(100%6+70%6+5%6)%6;
int sum=;
for(int i=;i<na.len;i++)
sum=(sum*+a[i]-'')%n;
return sum;
a%m=a%m%m,多取几次模对低位是没有影响的。
该题:
int sum=;
for(int i=; i<p.l; i++)//p.l密码的长度
{
sum=(sum*c+p.str[i])%n;//c是几进制
}
return sum;
3、队列基本操作:
back()返回最后一个元素
empty()如果队列空则返回真
front()返回第一个元素
pop()删除第一个元素
push()在末尾加入一个元素
size()返回队列中元素的个数
#include<stdio.h>
#include<string.h>
#include<queue>
#include<iostream>
#include<algorithm>
using namespace std;
char mm[];
int book[],out[],n,c,m;
int flag;
struct node
{
int str[];//存密码
int l;//密码长度
} p,q;
void shuchu(node p)
{
for(int i=; i<p.l; i++)
{
if(p.str[i]<=)
printf("%d",p.str[i]);
else
printf("%c",p.str[i]+);
}
flag=;
printf("\n");
return ;
} int quyu(node p)
{
// int sum=p.str[p.l-1];
// for(int i=p.l-2; i>=0; i--)
// {
// sum=(sum+(p.str[i]*c)%n)%n;
// c=c*c;
// }
// return sum;
int sum=;
for(int i=; i<p.l; i++)
{
sum=(sum*c+p.str[i])%n;
}
return sum;
}
void bfs()
{
memset(out,,sizeof(out));//标记余数
queue<node>Q;
p.l=;
int yushu;
for(int i=; i<; i++) //先走第一遍,让系统给的mm里面的每一个元素作为队头,因为可能第一遍给的数据就是最小倍数
//因为0不能作为开头,所以走第一遍的时候遍历从1开始;
{
if(book[i]==)//如果题目给了该数字
{
p.str[]=i;//后面的不断覆盖前面的,因为刚开始第一步只有一步
p.l=;//进来一个元素,长度改变为1,因为不断覆盖且只进行第一步,所以长度始终为1,不需要++
yushu=quyu(p);
if(yushu==)//说明找到了
{
shuchu(p);
flag=;
break;
}
else
{
//第一遍遍历没有找到,且如果这个余数之前没有出现过的话,把该余数标记一下
if(out[yushu]==)
{
out[yushu]=;
Q.push(p);//在队尾加入一个元素
}
}
//printf("%d--",flag);
}
}
while(!Q.empty())
{ if(flag)
break;
//node p;
p=Q.front();//返回到第一个元素
Q.pop();//删除第一个元素
for(int i=; i<; i++) //接着一条条队列开始进行搜索
{
if(book[i]==)//如果是题目给定的那几个数字就往下进行
{
//printf("%d-- ",i);
p.str[p.l]=i;//之前第一遍遍历的时候存的位置是l=0的位置,后来l变成1了,所以这里不需要++,直接占用l=1的位置
//之后再++,给下一位存入的数字留一个位置
p.l++;
yushu=quyu(p);
if(yushu==)//找到了
{
shuchu(p);
flag=;
break;
}
else
{
//if(out[yushu]==0&&(a.l-1<=497))//注意一下长度需要控制,并且是从l=0开始存的
if(out[yushu]==&&(p.l<=))
{
out[yushu]=;
Q.push(p);
}
p.l--;//这步很重要,非常重要
}
}
}
}
return ;
}
int main()
{
int t;
while(~scanf("%d",&t)&&t)
{
while(t--)
{
flag=;
memset(book,,sizeof(book));
scanf("%d %d",&n,&c);
scanf("%d",&m);
// for(int i=0; i<m; i++)
// {
// scanf("%c",&mm[i]);
// if(mm[i]>='0'&&mm[i]<='9')
// book[mm[0]-48]=1;
// if(mm[i]>='A'&&mm[i]<='F')
// //book[mm[i]-65+10]=1;
// book[mm[i]-55]=1;
// }//注意一下这里的输入,不能用%c,因为它接收空格,一开始记错了
for(int i=; i<m; i++)
{
scanf("%s",mm);
if(mm[]>=''&&mm[]<='')
book[mm[]-]=;
if(mm[]>='A'&&mm[]<='F')
//book[mm[i]-65+10]=1;
book[mm[]-]=;
}
if(n==)
{
if(book[]==)//说明给的几个数中没有0,该密码无法构成,故不存在
printf("give me the bomb please\n");
if(book[]==)//说明给的几个数中有0,该密码最小倍数为0
printf("0\n");
}
else
{
bfs();
if(flag==)//return为0,说明没有找到密码,不然就在上面输出了(return为1)
printf("give me the bomb please\n");
}
}
}
return ;
}
HDU-1226-超级密码-队列+广搜+大数取模的更多相关文章
- HDU 1226 超级密码(数学 bfs)
传送门: http://acm.hdu.edu.cn/showproblem.php?pid=1226 超级密码 Time Limit: 20000/10000 MS (Java/Others) ...
- hdu.1226.超级密码(bfs)
超级密码 Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Sub ...
- hdu 1226 超级密码
超级密码 Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Problem D ...
- HDU 1226 超级密码(BFS) (还需研究)
Time Limit:10000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u Submit Status Desc ...
- HDU 1226 超级密码 (搜素)
题目地址:http://acm.hdu.edu.cn/showproblem.php?pid=1226 题意简单,本来是一道很简单的搜素题目. 但是有两个bug: 1.M个整数可能有重复的. 2.N可 ...
- hdu 1226 超级密码(bfs+余数判重)
题意:略过 分析:用m个数字组成一个能够被n整除的c进制数的最小值,实际上本题的关键就在于这个最小值上. 首先确定我们的思路是从小到大寻找.先查看一位数,即查看着m个数字是否能被n整除:若不能,就查 ...
- 【HDU 5832】A water problem(大数取模)
1千万长度的数对73和137取模.(两个数有点像,不要写错了) 效率要高的话,每15位取一次模,因为取模后可能有3位,因此用ll就最多15位取一次. 一位一位取模也可以,但是比较慢,取模运算是个耗时的 ...
- 题解报告:hdu 1212 Big Number(大数取模+同余定理)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1212 Problem Description As we know, Big Number is al ...
- hdu2302(枚举,大数取模)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2303 题意:给出两个数k, l(4<= k <= 1e100, 2<=l<=1 ...
随机推荐
- jquery中的ajax方法参数的用法和他的含义
jquery中的ajax方法参数的用法和他的含义: 1.url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. 2.type: 要求为String类型的参数,请求方式(pos ...
- leetcode-1053. 交换一次的先前排列
题目描述: 给你一个正整数的数组 A(其中的元素不一定完全不同),请你返回可在 一次交换(交换两数字 A[i]和 A[j] 的位置)后得到的.按字典序排列小于 A 的最大可能排列. 如果无法这么操 ...
- 真实的『REM』手机屏幕适配
rem 作为一个低调的长度单位,由于手机端网页的兴起,在屏幕适配中得到重用.使用 rem 前端开发者可以很方便的在各种屏幕尺寸下,通过等比缩放的方式达到设计图要求的效果. rem 的官方定义『The ...
- ajax实现异步刷新
1. 导入 json 包: jackson-annotations-2.8.9.jar jackson-core-2.8.9.jar jackson-databind-2.8.9.jar json.j ...
- 利用MySqlBulkLoader生成csv文件,批量添加数据
DataTable dt = new DataTable(); dt.Columns.Add("Id", typeof(int)); dt.Columns.Add("Yw ...
- Vue下渐变效果有时候失效
记录一个问题:我在项目中给按钮设置一个渐变属性,调试的时候有时候有效果,有时候又没有,代码如下: .training-right-bmz { background: -webkit-linear-gr ...
- springmvc Cacheable
直接上代码: <cache:annotation-driven /> <bean id="cacheManager" class="org.spring ...
- vue组件基础之父子传值
可以看出数据从后端获取过来,最外层的父组件接收数据,子组件不能直接获取,必须由父组件传递,此时使用props,并且父组件的值更新后,子组件的值也会随之更新,但是反过来通过修改子组件props来影响父组 ...
- 保护Laravel .env文件,防止直接访问
web服务器: Apache 服务器系统: Ubuntu 14.04 如果不是vhost的形式部署在服务器上,可能是可以通过 http://www.example.com/.env 查看到larave ...
- 每天进步一点点-WPF-根据数据类型加载控件
目的,根据数据类型的不同,动态的加载适用于不同数据类型的控件(布局) 原理:为自定义的数据类型添加数据魔板,绑定的时候绑定这些数据类型的实例. 例子: 数据类型: 数据模板: <DataTemp ...