思路:
首先给出一个结论,就是最多用两个数就可以表示任何数的倍数。
证明 :对于一个数字a,可以构造出的数字有
a,aa,aaa,aaaa,aaaaa,……
每一个数对于n都有一个余数,余数最多有n个,根据鸽巢原理,前n+1个数中,必然有两个余数相等
那么二者之差,必定为n的倍数,形式为a……a0……0。
有这个结论,就简单了
先枚举一个数,然后枚举两个数,BFS即可
代码如下:
1 #include<iostream> 2 #include<stdio.h> 3 #include<algorithm> 4 #include<iomanip> 5 #include<cmath> 6 #include<cstring> 7 #include<vector> 8 #include<queue> 9 #define MAX 10001 10 using namespace std; 11 string ans,str; 12 int n,k,m,num[MAX],vis[MAX],next[MAX]; 13 bool bfs() 14 { 15 queue<int>p; 16 memset(vis,-1,sizeof(vis)); 17 for(int i=0;i<m;i++) 18 if(num[i]){ 19 p.push(num[i]); 20 vis[num[i]]=num[i]; 21 next[num[i]]=-1; 22 } 23 while(!p.empty()){ 24 int e=p.front(); 25 p.pop(); 26 if(!e) return true; 27 for(int i=0;i<m;i++){ 28 int t=(e*k+num[i])%n; 29 if(vis[t]==-1){ 30 vis[t]=num[i]; 31 next[t]=e; 32 p.push(t); 33 } 34 } 35 } 36 return false; 37 } 38 bool cmp(string a,string b) 39 { 40 if(b.size()==0) return true; 41 if(a.size()>b.size()) return false; 42 if(a.size()<b.size()) return true; 43 return a<b; 44 } 45 void solve(int k) 46 { 47 if(next[k]!=-1) solve(next[k]); 48 str+=(char)(vis[k]+'0'); 49 } 50 int main(){ 51 while(cin>>n>>k){ 52 if(n<k){ 53 cout<<n<<endl; 54 continue; 55 } 56 bool flag=0;ans=""; 57 for(int i=1;i<k;i++){ 58 num[0]=i; 59 m=1; 60 if(bfs()){ 61 str=""; 62 solve(0); 63 flag=true; 64 if(cmp(str,ans)) 65 ans=str; 66 } 67 } 68 if(!flag){ 69 for(int i=1;i<k;i++) 70 for(int j=0;j<i;j++){ 71 num[0]=j;num[1]=i; 72 m=2; 73 if(bfs()){ 74 str=""; 75 solve(0); 76 if(cmp(str,ans)) 77 ans=str; 78 } 79 } 80 } 81 cout<<ans<<endl; 82 } 83 return 0; 84 }