题目链接: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 }