嗯,做了一道和上一题类似的题,卡时真心坑爹啊。。。
有一个地方没有搞懂,就是为什吗长度是2
a,aa,aaa,aaaa.....aaaaaa..aaaa
这样的数每生成一个,对n取模得到一个数b,记录数组b[i],当i=n+1时,根据鸽巢原理,必有i,j使得b[i]=b[j]
把a[i]和a[j]相减,得到aaaaa...00000 肯定存在n的倍数只有2个数字
接下来枚举就是了
用pair超时,估计字符串太长了,然后后来去掉pair之后,还是TLE,再用全局变量记录当前长度,这样才能过,卡时间卡成狗啊
#include <iostream>
#include <cstdio>
#include <string>
#include <queue>
#define N 10005
#define cl(a) memset(a,0,sizeof(a))
#define ss(a) scanf("%d",&a)
using namespace std;
int n,k,flag,Mlen;
int h[N],num[3],pre[N],dig[N];
string res;
queue<int>rec;
string mining(string sx,string sy)
{
int lx=sx.length();
int ly=sy.length();
if (lx<ly) return sx;
else if (lx>ly) return sy;
else
{
if (sx<sy) return sx;
else return sy;
}
}
string solve(int x)
{
if (x==-1) return "";
else
{
char ch=dig[x]+'0';
return solve(pre[x])+ch;
}
}
int bfs(int m)
{
int u=0;
while (!rec.empty()) rec.pop();
rec.push(u);
int i,j;
while (!rec.empty())
{
int curr = rec.front();
if (h[curr]>=Mlen)
{
rec.pop();
continue;
}
for (j=0;j<m;j++)
{
i=num[j];
if (!curr&&!i) continue;
int x=(curr*k+i)%n;
if (!h[x])
{
if (curr>0)
{
h[x]=h[curr]+1;
pre[x]=curr;
}
else
{
h[x]=1;
pre[x]=-1;
}
dig[x]=i;
if (x==0)
{
flag=1;
return 1;
}
rec.push(x);
}
}
rec.pop();
}
return 0;
}
void deal()
{
string ss=solve(0);
if (res=="") res=ss;
else res=mining(res,ss);
int l=res.length();
Mlen=min(Mlen,l);
}
int main()
{
int i,j;
while (ss(n)!=EOF)
{
ss(k);
res="";
flag=0;
Mlen=N*2;
for (i=1;i<k;i++)
{
cl(h);
num[0]=i;
if (bfs(1))deal();
}
if (flag)
{
cout<<res<<endl;
continue;
}
for (i=0;i<k;i++)
for (j=i+1;j<k;j++)
{
cl(h);
num[0]=i;num[1]=j;
if (bfs(2)) deal();
}
cout<<res<<endl;
}
return 0;
}