hdu 4294(bfs)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4294

思路:题目的意思是说,给你n,k,则求出n的正整数倍数,使得这个数字在k进制下表示的时候需要的不同数字最小。首先明确最多的不同数字需要2种,证明如下a,aa,aaa,aaaa,......找出n个连续的,那么中间至少有两个mod n的值是相等的,那么这两个数字相减,得到aaa...000肯定能被n整除,因此可以bfs搜索只含有1个数字的和只含有2个数字的。

  1 #include<iostream>
  2 #include<cstdio>
  3 #include<cstring>
  4 #include<algorithm>
  5 #include<string>
  6 using namespace std;
  7 #define MAXN 77777
  8 
  9 struct Node{
 10     int num,val,pre,len;
 11 }que[MAXN];
 12 
 13 int number[4];
 14 int n,k,min_len,length,flag,End;
 15 string ans,tmp;
 16 bool mark[MAXN];
 17 
 18 bool bfs(int m)
 19 {
 20     Node now,next;
 21     memset(mark,false,sizeof(mark));
 22     int head=0,tail=-1;
 23     for(int i=1;i<=m;i++)if(number[i]){
 24         now.len=0;
 25         now.num=number[i];
 26         now.pre=-1;
 27         now.val=number[i]%n;
 28         que[++tail]=now;
 29         mark[now.val]=true;
 30     }
 31     while(head<=tail){
 32         now=que[head];
 33         if(now.len>min_len)break;
 34         if(now.val==0){
 35             End=head;
 36             length=now.len;
 37             return true;
 38         }
 39         for(int i=1;i<=m;i++){
 40             next=now;
 41             next.val=(now.val*k+number[i])%n;
 42             if(!mark[next.val]){
 43                 mark[next.val]=true;
 44                 next.len++;
 45                 next.num=number[i];
 46                 next.pre=head;
 47                 que[++tail]=next;
 48             }
 49         }
 50         head++;
 51     }
 52     return false;
 53 }
 54 
 55 void Get_String(int k)
 56 {
 57     if(k==-1)return ;
 58     Get_String(que[k].pre);
 59     tmp+=(que[k].num+'0');
 60 }
 61 
 62 int main()
 63 {
 64     while(~scanf("%d%d",&n,&k)){   //input整数n和k进制
 65         ans="";
 66         min_len=1000000000;
 67         flag=0;
 68         for(int i=1;i<k;i++){   //先搜索只有1个数字的
 69             number[1]=i;
 70             if(bfs(1)){
 71                 flag=1;
 72                 tmp="";
 73                 Get_String(End);
 74                 if(length<min_len||(length==min_len&&tmp<ans)){
 75                     ans=tmp;
 76                     min_len=length;
 77                 }
 78             }
 79         }
 80         if(flag){
 81             cout<<ans<<endl;
 82             continue;
 83         }
 84         for(int i=0;i<k;i++){    //搜索2个数字的
 85             number[1]=i;
 86             for(int j=i+1;j<k;j++){
 87                 number[2]=j;
 88                 if(bfs(2)){
 89                     tmp="";
 90                     Get_String(End);
 91                     if(length<min_len||(length==min_len&&tmp<ans)){
 92                         ans=tmp;
 93                         min_len=length;
 94                     }
 95                 }
 96             }
 97         }
 98         cout<<ans<<endl;
 99     }
100     return 0;
101 }
View Code

 

posted @ 2013-09-03 22:08  ihge2k  阅读(265)  评论(0编辑  收藏  举报