码迷,mamicode.com
首页 > 其他好文 > 详细

HDU ACM 4474 Yet Another Multiple Problem->数论(数位BFS)

时间:2015-06-09 13:50:11      阅读:118      评论:0      收藏:0      [点我收藏+]

标签:c   c++   acm   算法   编程   

题意:n和m,m个十进制的单位数字(0-9),求最小的数ans,使ans是n的倍数(除0),且ans中不包括输入的十进制数字。不存在输出-1。

使用BFS搜索,从小向大枚举可以保证构造出来的数是递增的,若不加判断直接搜索的话,复杂度非常高。如果一个数%N==0,这个数就是N的倍数。在没有找到的时候,若A%N==B%N,且A<B,那么其实可以取A而不取B,因为如果在A末尾增加C可以使得AC%N==0,那么BC%N也等于0,可知如果A和B追加数之后%N==0,最优条件下追加的数肯定相同。因此只需维护组合出来的数%N的值即可,如果在搜索的途中出现了相同的%N值,就可以忽略了,肯定没有前面的更好。

#include<iostream>
#include<queue>
using namespace std;

#define N 10010

int p[N];      //pre[v]记录到达v的前一节点u
int num[N];    //num[v]记录形成v的最后一位数字
bool a[10];    //被除去的数据
int n;

void Init()
{
	memset(p,-1,sizeof(p));
	memset(num,-1,sizeof(num));
	memset(a,false,sizeof(a));
}

void Show(int u)        //递归打印结果
{
	if(p[u]!=-1)
		Show(p[u]);
	printf("%d",num[u]);
}

void bfs()
{
	int i,t,u;
	queue<int> q;

	for(i=1;i<10;i++)  //注意0不算,要除去
		if(!a[i])
		{
			t=i%n;
			if(t==0)             //结果只有一位数字的情况
			{
				printf("%d",i);
				return ;
			}
			q.push(t);
			num[t]=i;
		}
	while(!q.empty())
	{
		u=q.front();
		q.pop();
		for(i=0;i<10;i++)
			if(!a[i])
			{
				t=(10*u+i)%n;
				if(num[t]==-1) //之前未出现过
				{
					q.push(t);
					p[t]=u;
					num[t]=i;
				}
				if(t==0)
				{
					Show(t);
					return ;
				}
			}
	}
	printf("-1");
}

int main()
{
	int k=0,m,x;

	while(scanf("%d%d",&n,&m)==2)
	{
		Init();
		while(m--)
		{
			scanf("%d",&x);
			a[x]=true;
		}
		printf("Case %d: ",++k);
		bfs();
		putchar('\n');
	}
	return 0;
}


HDU ACM 4474 Yet Another Multiple Problem->数论(数位BFS)

标签:c   c++   acm   算法   编程   

原文地址:http://blog.csdn.net/a809146548/article/details/46425589

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!