Subject to the effect:
Topic links: https://www.luogu.org/problemnew/show/P2841
given a number
, you need to give a minimum number
, such that
and
product contains only 0 and 1.
Ideas:
All processing precision is not explained.
Obviously binary enumeration violence will timeout. Because it will enumerate enumeration completely unnecessary to count the number of the lot.
If the
and
two meet number 01
且
, then
and
end plus a 0 or a 1, these two numbers
also congruence. In this case large numbers
it is completely unnecessary to enumerate the prefix
numbers do not need to enumerate. Because there is always a little more than its numbers and its congruence, and we ask for is the smallest of the answer.
So you can use
to enumerate the number 01, to enumerate 0, then enumeration 1, so as to ensure the number 01 is enumerated in ascending order of enumeration. At the same time use
to determine the number (the array can be used directly over.
), the same as if you already have a number and the number of remainder, then this would not have continued to enumerate the number down.
Find the answer on exit
, because when we have to ensure that the search of the answer as small as possible.
Then in addition to high-precision single actuarial first answer, the second answer is
.
Code:
#include <queue>
#include <cstdio>
using namespace std;
const int N=10010,M=200;
int n,a[N];
bool hash[N],flag;
struct node
{
int a[M+1],p,len;
}ans1,ans2;
queue<node> q;
node xx;
void bfs()
{
xx.len=1; xx.a[1]=1; xx.p=1; q.push(xx);
hash[1]=1;
while (q.size())
{
node u=q.front();
q.pop();
if (!u.p)
{
ans1=ans2=u;
return;
}
for (int i=0;i<=1;i++)
{
int p=(u.p*10+i)%n;
if (!hash[p])
{
hash[p]=1;
node v=u;
v.len++;
v.a[v.len]=i;
v.p=p;
q.push(v);
}
}
}
}
int main()
{
scanf("%d",&n);
if (n==1) return !printf("1 1\n");
bfs();
for (int i=1;i<=ans1.len;i++)
{
a[i]=ans1.a[i]/n;
ans1.a[i+1]+=ans1.a[i]%n*10;
}
int i=1;
while (!a[i]) i++;
for (;i<=ans2.len;i++) printf("%d",a[i]);
putchar(32);
for (i=1;i<=ans2.len;i++) printf("%d",ans2.a[i]);
return 0;
}