首页 > 代码库 > (BFS)poj1465-Multiple
(BFS)poj1465-Multiple
题目地址
题意可理解为我们有一些给定的元素,要用它们组成数,如果一个长度(x)所有组成的数都不是给定的另一个数(n)的倍数,并且长度为x的数中有模n的不同于长度小于x的数模n的数,那么继续延长这个数的长度。这样进行到无法进行下去时,就是要输出0的情况,中途如果找到了n的倍数,就直接返回输出。题目比较关键的是我们只需关注模n意义下的情况,这样就省略了很多细枝末节没有影响的数,并且有效的控制了数的大小,使之在我们可以接受的范围内。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; int n,m,digit[10],an;//digit数组用于储存题目中可以出现的数(因为都是个位数,所以大小设为10) struct node { int yu;//这个数模n的余数 int digit;//这位的数码 int pre;//这一位前一位的数 }q[5052];//建立一个结构体,方便操作 bool flag[5052];//通过bool数组记录某一个余数是否出现过 int bfs() { memset(flag,0,sizeof(flag)); int front=0,tail=1; q[front].yu=0; q[front].pre=-1;//将第一个的pre初始化为不可能取得的数,进行后面的判断 q[front].digit=0; while(front<tail)//继续进行的条件 { node p=q[front]; int r=p.yu;//之前的余数 for(int i=0;i<m;i++) { int nr=(10*r+digit[i])%n;//新的余数 if(!flag[nr]&&(p.pre!=-1||digit[i]!=0))//如果没有出现过这个余数,并且满足不是第一位或这一位是0条件之一(因为往后不可以出现0,只是加0不改变余数) { flag[nr]=true; p.pre=front; p.digit=digit[i]; p.yu=nr; q[tail++]=p; if(nr==0) return tail-1; } } front++; } return -1; } void print(int x)//比较巧妙的输出方式,学习了 { if(x>0) { print(q[x].pre); printf("%d",q[x].digit); } } int main() { while(scanf("%d",&n)==1) { scanf("%d",&m); for(int i=0;i<m;i++) scanf("%d",&digit[i]); if(n==0)//0要单独讨论一下 {printf("0\n"); continue;} sort(digit,digit+m); int an=bfs(); if(an==-1) printf("0\n"); else {print(an); puts("");} } return 0; }
(BFS)poj1465-Multiple
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。