hdu 1226 超级密码 bfs+大整数对long取模

本文介绍了一种通过广度优先搜索寻找最小整除密码的方法。该算法从高位开始逐位扩展,利用模运算进行强剪枝,确保找到的密码是最小的且为指定数值的整数倍。
题意:一个密码位数不超过500,且最高位不为0,它是一个由m个数字组成的c进制数,并且密码是N的整数倍里最小那个,将其输出,如果不存在输出give me the bomb please。
思路:从高位开始,每添加一位,则扩展m个状态,判断每个状态代表的数字能否整除n,如果能就是符合题意的密码,不能将这个余数标记,是个强剪枝,因为同余的数,后面一位再添加相同的数还是同余,所以访问一次就行了,如果状态跑完(密码的长度>500),都没找到,则说明不存在。
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
bool num[17];
int N,C;
char s[10];
int vis[6000];
struct node
{
	int s[550];
	int len;
};
int mod(node a)
{
	int temp=0;
	for(int i=0;i<a.len;i++)
	{
		temp=(temp*C+a.s[i])%N;
	}
	return temp;
}
void print(node a)
{
	for(int i=0;i<a.len;i++)
	{
		if(a.s[i]>=0&&a.s[i]<=9)printf("%d",a.s[i]);
		else printf("%c",a.s[i]-10+'A');
	}
	printf("\n");
}
bool bfs()
{
	memset(vis,0,sizeof(vis));
	queue<node> q;
	node a;
	a.len=0;
	for(int i=1;i<16;i++)//特判第一位 
	{
		if(num[i])
		{
			a.s[0]=i;
			a.len=1;
			int r = mod(a);
			if(!r)
			{
				print(a);
				return 1;
			}
			else if(!vis[r])
			{
				vis[r]=1;
				q.push(a);
			}
		}
	}
	while(!q.empty())
	{
		node a = q.front();q.pop();
		for(int i=0;i<16;i++)
		{
			if(num[i])
			{
				a.s[a.len]=i;
				a.len++;
				int r = mod(a);
				if(!r)
				{
					print(a);
					return 1;
				}
				else if(!vis[r]&&a.len<499)
				{
					vis[r]=1;
					q.push(a);
				}
				a.len--;//重复试探第len位,此len与压入栈中的a.len不同 
			}
		}
	}
	return 0;
}
int main()
{
	int T;
	//freopen("in.txt","r",stdin);
	scanf("%d",&T);
	while(T--)
	{
		int M;
		memset(num,0,sizeof(num));
		scanf("%d%d%d",&N,&C,&M);
		for(int i=0;i<M;i++)
		{
			scanf("%s",s);
			if(s[0]>='0'&&s[0]<='9')
			num[s[0]-'0']=1;
			else
			num[s[0]+10-'A']=1;
		}
		if(N==0)
		{
			if(num[0])
			printf("0\n");
			else
			printf("give me the bomb please\n");
		}
		else
		{
			int flag=bfs();
			if(!flag)
			printf("give me the bomb please\n");
		}
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值