题目描述:给你n,k,则求出n的正整数倍数,使得这个数字在k进制下表示的时候需要的不同数字最小
首先明确最多的不同数字需要2种,证明如下
a,aa,aaa,aaaa,......找出n个连续的,那么中间至少有两个mod n的值是相等的,那么这两个数字相减,得到aaa...000肯定能被n整除
直接暴力搜索每一种情况//至多两个数字就可以拼出任何数的倍数
//给你n,k,则求出n的正整数倍数,使得这个数字在k进制下表示的时候需要的不同数字最小
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=10002;
int n,c,k,l,l1;
int pre[N],res[N],step[N],num[2];
char ans[N],re[N];
bool bfs() //判断c个数能否组成n的倍数
{
queue<int> Q;
int i,p,q;
memset(step,0,sizeof(step));
for(i=0;i<c;i++)
{
int y=num[i]%n;
if(num[i]==0||step[y])
{
continue;
}
step[y]=1;
pre[y]=-1;
res[y]=num[i];
Q.push(y);
}
while(!Q.empty())
{
p=Q.front();
Q.pop();
if(p==0)
{
return true;
}
if(l&&step[p]>l)
{
return false;
}
for(i=0;i<c;i++)
{
q=(p*k+num[i])%n;
if(!step[q])
{
step[q]=step[p]+1;
pre[q]=p;
res[q]=num[i];
Q.push(q);
}
}
}
return false;
}
void solve(int i)
{
if(pre[i]!=-1)
{
solve(pre[i]);
}
re[l1++]=res[i]+'0';
}
bool judge() //比较大小
{
int i;
if(!l||l1<l)
{
return true;
}
if(l1>l)
{
return false;
}
for(i=0;i<l;i++)
{
if(ans[i]<re[i])
{
return false;
}
if(ans[i]>re[i])
{
return true;
}
}
return false;
}
int main()
{
int i,j;
while(~scanf("%d%d",&n,&k))
{
l=0;
bool flag=false;
for(i=1;i<k;i++)
{
num[0]=i;
c=1;
if(bfs())
{
flag=true;
l1=0;
solve(0);
if(judge())
{
l=l1;
memcpy(ans,re,sizeof(ans));
}
}
}
if(!flag)
{
for(i=0;i<k;i++)
{
for(j=i+1;j<k;j++)
{
num[0]=i;
num[1]=j;
c=2;
if(bfs())
{
l1=0;
solve(0);
if(judge())
{
l=l1;
memcpy(ans,re,sizeof(ans));
}
}
}
}
}
for(i=0;i<l;i++)
{
printf("%c",ans[i]);
}
putchar(10);
}
return 0;
}