首页 > 代码库 > URAL 1495. One-two, One-two 2

URAL 1495. One-two, One-two 2

找一个最小的数 不超过30位 只能由1 2组成的并且是n的倍数

先算出15位 dp[i]表示余数为i的最小的数 dp2[i]表示长度正好是15位余数为i的最小的数

#include <cstdio>
#include <cstring>
#include <map>
#include <cstdlib>
using namespace std;	
typedef long long LL;
LL dp[1000010], dp2[1000010];
void dfs(int i, LL x, LL n)
{
	LL tmp = x%n;
	if(!dp[tmp] || dp[tmp] > x)
	{
		dp[tmp] = x;
	}
	if(i == 15)
	{
		if(!dp2[tmp] || dp2[tmp] > x)
				dp2[tmp] = x;
		return;
	}
	dfs(i+1, x*10+1, n);
	dfs(i+1, x*10+2, n);
}
int main()
{
	int n;
	while(scanf("%d", &n) != EOF)
	{
		if(n == 1 || n == 2)
		{
			printf("%d\n", n);
			continue;
		}
		memset(dp, 0, sizeof(dp));
		dfs(0, 0, n);
		if(dp[0])
		{
			printf("%lld\n", dp[0]);
			continue;
		}
		LL tmp1 = -1, tmp2 = -1;
		
		for(int i = 1; i < n; i++)
		{
			if(!dp[i])
				continue;
			LL x = i;
			for(int i = 0; i < 15; i++)
				x = x*10%n;
		
			int tmp = n-x;	
			if(!dp2[tmp])
				continue;
			if(tmp1 == -1 || tmp1 > dp[i])
			{
				tmp1 = dp[i];
				tmp2 = dp2[tmp];
				//printf("%lld %lld %lld\n", x, dp[tmp], (x+tmp)%n);
			}
		}
		if(tmp1 == -1)
			puts("Impossible");
		else
			printf("%lld%lld\n", tmp1, tmp2);
	}
	return 0;
}
/*
10007
211222212122
999997
2112221121222222212212222

*/


URAL 1495. One-two, One-two 2