一个数论中的结论:对于任意的整数n,必然存在一个由不多于两个的数来组成的一个倍数。因为a,aa,aaa……取n+1个,则必有两个模n余数相同,相减即得n的倍数m。而m只由a、0组成。
原理很好懂,但实现好复杂,还没看懂,日后再补
#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#define maxn 65540
using namespace std;
int n,m,mcnt,tcnt,h;
int a[5];
bool vis[maxn];//取余判重
string ans,tans;
struct Node {
int d,val,pre; //val-有效值
int cnt;
}cur,now,q[maxn];
void getans(int k) { //递归得到ans 避免在结构体中添加string 每次操作string很费时间
char c;
if (k==-1) return;
else {
getans(q[k].pre);
c=q[k].d+'0';
tans+=c;
}
}
bool bfs(int k) {
int i,j,nval,ncnt,tval;
int head=0,tail=-1;
memset(vis,0,sizeof(vis));
for(i=1;i<=k;i++) {
if (a[i]) {
cur.cnt=0;
cur.d=a[i];
cur.pre=-1;
cur.val=a[i]%n;
vis[cur.val]=1;
q[++tail]=cur;
}
}
while(head<=tail) {
now=q[head];
nval=now.val;
ncnt=now.cnt;
if (ncnt>mcnt) break; //剪枝
if (!nval) {
h=head;
tcnt=ncnt;
return true;
}
for(i=1;i<=k;i++) {
tval=(nval*10+a[i])%n;
if (!vis[tval]) {
vis[tval]=1;
cur.cnt=ncnt+1;
cur.d=a[i];
cur.pre=head;
cur.val=tval;
q[++tail]=cur;
}
}
head++;
}
return false;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif
int i,j,flag;
while(scanf("%d",&n) && n!=0) {
flag=0;
ans="xx";
mcnt=1000000000;
for(i=1;i<=9;i++) {//先搜一个数能否组成n的倍数
a[1]=i;
if (bfs(1)) {
tans="";
getans(h);
if (mcnt>tcnt || mcnt==tcnt && ans>tans) {//注意比较ans的大小
ans=tans;
mcnt=tcnt;
}
}
}
if(ans!="xx") {
flag=1;
cout<<ans<<endl;
}
if (flag) continue;
for(i=0;i<=9;i++) { //再搜两个数
a[1]=i;
for(j=i+1;j<=9;j++) {
a[2]=j;
if (bfs(2)) {
tans="";
getans(h);
if (mcnt>tcnt || mcnt==tcnt && ans>tans) {
ans=tans;
mcnt=tcnt;
}
}
}
}
cout<<ans<<endl;
}
return 0;
}