[P2841] Luo Valley A * B Problem [High Precision] bfs

Subject to the effect:

Topic links: https://www.luogu.org/problemnew/show/P2841
given a number A A , you need to give a minimum number B B , such that A A and B B 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 x x and Y Y two meet number 01 x Y ( m O d   n ) x\equiv y(mod\ n) x < y x<y , then x x and y Y end plus a 0 or a 1, these two numbers m o d   n v \ N also congruence. In this case large numbers ( y ) (Y) it is completely unnecessary to enumerate the prefix y Y 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 b f s bfs 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 h a s h hash to determine the number (the array can be used directly over. n 1 0 4 n \ leq 10 ^ 4 ), 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 b f s bfs , 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 a n s years .


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;
}

Guess you like

Origin blog.csdn.net/SSL_ZYC/article/details/94710122