/*
和poj2283是同一道題
111111就是一個元素,12222就是連個元素。
思路:
對於任意的整數 n ,必然存在一個由不多於兩個的數來組成的一個倍數。 因爲 a , aa , aaa…… 取 n+1 個,
則由鴿籠原理(抽屜原理),必有兩個模 n 餘數相同,相減即得 n 的倍數 m 。而 m 只由 a 、 0 組成。
對於餘數相同的情況,數位少的含不同數字的個數肯定不超過數位多的,所以可以用餘數判重。
*/
#include<stdio.h>
int pr[2][65540],q[65536*2],p[65536*2],n;//pr數組是輸出數組,q[]是隊列數組,p是隊列的前指針數組
int bfs(int a,int b,int t)
{
int fr=0,r=1,f[65540]= {0},i;//fr存的是隊列的前指針,r存的時候指針,f是餘數標記數組
q[0]=0;//q這個隊列的元素是一個個餘數
p[0]=0;
if(a==0)//當a爲零時,a不能在數的開頭,爲了下面還原數的的時候,保持奇偶性不變
{
q[2]=b;
p[2]=0;
fr=2;
r=3;
}
while(fr<r)
{
if(f[q[fr]]==1)//因爲入隊時我們沒有判斷餘數是否出現過,所以開頭的時候,先判斷餘數是否出現過
{
fr++;
continue;
}
f[q[fr]]=1;//沒出現過的餘數把它標記爲已經搜過
q[r]=(q[fr]*10+a)%n;//用餘數去搜a
p[r]=fr;//記錄fr的值,表明q[r]這個餘數是由q[fr]搜過來的
if(q[r]==0)//餘數爲0跳出循環
break;
r++;//隊列的後指針向後移一位,因爲a已經搜過
q[r]=(q[fr]*10+b)%n;
p[r]=fr++;//fr向後移一位,因爲q[fr]已經搜過a,b了需要向下搜索
if(q[r]==0)
break;
r++;
}
if(fr<r)
{
for(i=0; r!=0; i++)
{
if(r%2==0)//當r爲偶數時搜的一定是b
pr[t][i]=b;
else
pr[t][i]=a;
r=p[r];//把r退回到上一層指針
}//這樣我們就把數還原了出來,但是是倒序存的
return i-1;
}
return -1;
}
int main()
{
int i,j,m,t,c;
while(scanf("%d",&n)!=EOF&&n!=0)
{
int d[10];
c=0;
d[0]=n;
for(i=1; i<=9; i++)//判斷一個元素是否是n的倍數
{
d[i]=1;
j=i;
while(d[i]<n&&j%n!=0)//j%n是一個技巧
{
j=(j*10+i)%n;
d[i]++;
}
if(d[i]<d[c])//當d[i]<d[c]的時候說明找到了一個更小的
c=i;
}
if(c!=0)//當c非等於0時就說明一個元素的存在,且爲d[c]個c
{
for(i=0; i<d[c]; i++)
printf("%d",c);
}
else
{
t=0;//t這個變量也是一個技巧,當我們判斷一個數是否大於上一個數的時候,不需要再把這個數複製一遍,直接在廣搜把這個數覆蓋就可以了
m=n;//m一隻記錄的是當前數的位數,如果找到小於m的就更新m的值
for(i=0; i<10; i++)
for(j=i+1; j<10; j++)
{
c=bfs(i,j,t);
if(c!=-1&&c<m)//如果c小於m的話就更新m的值
{
m=c;
t=t^1;//廣搜還原數的時候還原到相對的位置如果t是0就還原到pr[1][]數組裏否則就是pr[0][]數組裏
}
else if(c==m)//當c==m的話就要比較兩個數的大小
{
for(int k=m; k>=0; k--)//因爲我們還原出來的數是倒序,所以比較的時候也應該從後往前
{
if(pr[t][k]>pr[1-t][k])
{
break;
}
else if(pr[t][k]<pr[1-t][k])
{
t=t^1;
break;
}
}
}
}//最後t只記錄的較大的那個數行所以1-t或者1^t
for(i=m; i>=0; i--)//倒序輸出這個數
printf("%d",pr[1^t][i]);
}
printf("\n");
}
return 0;
}