您的位置:首页 > 其它

hdu 4474 Yet Another Multiple Problem ( bfs + math)

2013-10-21 23:25 453 查看
题意:求给定数n的最小的倍数,使其中不包含给出的m个十进制数。

状态太多了。。。参看别人的思路,

就是在每一位上对可以出现的数进行枚举,然后bfs。。。直到出现第一个节点中m==0,就输出。

每个节点记录三个值

c:末尾的那个数字

m:这个节点所代表的数字对n取模的值

f:父节点

对于一个节点,如果在其后面加一个数字i,那么新的m值=(m*10 + i)%n

显然,如果答案存在,那么我们第一个找到的m==0的节点就是答案,然后再用一个递归逆序输出就好。

可以发现,新节点的m的值只与父节点的m值有关,所以,对于相同的m,只有第一个出现m的节点是有用的。

参考来源:点击打开链接

第一次写“这样”的bfs。。。
在l 和 r间移动。。。。长见识。。。长思维。。。click zan~

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;

struct node
{
char c;
int m,f;
}d[10010],tmp;
bool h[10010],g[10];

void out(int a)
{
if(a==-1) return;
out(d[a].f);
putchar(d[a].c);
}

int main()
{
int cas=0,n,m,l,r;
while(scanf("%d%d",&n,&m)!=EOF)
{
printf("Case %d: ",++cas);
memset(g,false,sizeof(g));
memset(h,false,sizeof(h));
int ans = -1;

for(int i=0;i<m;i++)
{
int x;
scanf("%d",&x);
g[x]=true;
}

l=r=0;

for(int i=1;i<10;i++)
{
if(g[i]==false)
{
tmp.c = i+'0';
h[tmp.m=i%n] = true;
tmp.f = -1;
d[r++]=tmp;

if(tmp.m==0)
{
ans = r-1;
break;
}
}
}
while(l<r && ans == -1)
{
for(int i=0;i<10;i++)
{
if(g[i]==false)
{
tmp.c = i+'0';
tmp.m = (d[l].m*10+i)%n;
if(h[tmp.m]==false)
{
h[tmp.m]=true;
tmp.f = l;
d[r++]=tmp;
if(tmp.m == 0)
{
ans = r-1;
break;
}
}
}
}
l++;
}
if(ans==-1) puts("-1");
else
{
out(ans);
putchar('\n');
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: