现在的位置: 首页 > 综合 > 正文

伊甸园日历游戏 && 飘飘乎居士拯救MM(tyvj 1968 && 1140)

2014年09月29日 综合 ⁄ 共 2269字 ⁄ 字号 评论关闭

tyvj 1968:

我的方法,将SG值打出来,然后就可以看到规律。

具体的想法可以看------>点击打开链接

#include <stdio.h>
#include <string.h>

int sg[15][35];
int day[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};

int getsg(int x, int y)
{
	if(sg[x][y] != -1)
		return sg[x][y];
	bool vis[100];
	memset(vis, 0, sizeof(vis));
	
	if(x < 10 || x == 10 && y <= 4)
		vis[getsg(x + 1, y)] = 1;
	if(y != day[x] && x != 12)
		vis[getsg(x, y + 1)] = 1;
	else
		vis[getsg(x + 1, 1)] = 1;
		
	int i;
	for(i = 0; i < 100; i++)
		if(vis[i] == 0)
			break;
	return sg[x][y] = i;
}

int getsg1(int x, int y)
{
	if(sg[x][y] != -1)
		return sg[x][y];
	bool vis[100];
	memset(vis, 0, sizeof(vis));
	if(x == 12)
	{
		if(y != 31)
			vis[getsg(x, y + 1)] = 1;
		else
			vis[getsg(1, 1)] = 1;
		vis[getsg(1, y)] = 1;
	}
	
	if(x == 11)
	{
		if(y != 30)
			vis[getsg(x, y + 1)] = 1;
		else
			vis[getsg(x + 1, 1)] = 1;
		vis[getsg(x + 1, y)] = 1;
	}
	int i;
	for(i = 0; i < 100; i++)
		if(vis[i] == 0)
			break;
	return sg[x][y] = i;
}


int main (void)
{
	memset(sg, -1, sizeof(sg));
	sg[11][4] = 0;
	sg[11][3] = 1;
	sg[11][2] = 0;
	sg[11][1] = 1;
	int i, j;
	for(i = 10; i > 0; i--)
		for(j = day[i]; j > 0; j--)
			getsg(i, j);

	for(i = day[12]; i > 0; i--)
		getsg1(12, i);
	for(i = day[11]; i >= 5; i--)	
		getsg1(11, i);
			
	for(i = 1; i <= 12; i++)
	{
		printf("%d: ", i);
		for(j = 1; j <= day[i]; j++)
		{
			if(sg[i][j] != 0)
				printf("1 ");
			else
				printf("0 ");
		}
		printf("\n");
	}
	return 0;
	
}

打表结果:

1: 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
2: 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
3: 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
4: 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
5: 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
6: 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
7: 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1
8: 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
9: 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1
10: 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0
11: 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 1
12: 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0

#include <stdio.h>

int main (void)
{
	int t;
	scanf("%d", &t);
	while(t --)
	{
		int y, m, d;
		scanf("%d %d %d", &y, &m, &d);
		if((m + d) % 2 == 0)
				printf("YES\n");
		else
		{
			if((m == 11 || m == 9) && d == 30)
				printf("YES\n");
			else	
				printf("NO\n");
		}
	}
	return 0;
}

tyvj 1140:

用到了德巴赫猜想:

1.每个不小于6的偶数都可以表示为两个奇素数之和
2.每个不小于9的奇数都可以表示为三个奇素数之和

所以只要输入的是一个偶数,那么它可以通过2步完成,输入的是一个奇数,那么需要3步完成。
但是,有一些需要注意的地方:
1 如果这个数本身就是质数或者1,那么只需要一步
2 如果一个数减去2以后是质数,那么它也只需要2步(只有奇数才会执行)

#include <stdio.h>
#include <limits>

int isprime(int x)
{
	int i;
	for(i = 2; i * i <= x; i++)
		if(x % i == 0)
			return 0;
	return 1;
}


int get(int x)
{
	if(x <= 2)
		return 1;
	if(isprime(x))//是素数 
		return 1;
	if(x % 2 == 0)//偶数 
		return 2;
	if(isprime(x - 2))//奇数减2是素数 
		return 2;
	return 3;//奇数 
}

int main (void)
{
	int t;
	scanf("%d", &t);
	while(t --)
	{
		int a, b, c, d;
		scanf("%d %d", &a, &b);
		c = get(a);
		d = get(b);
		if(a > b)
		{
			if(c <= d)
				printf("YES\n");
			else
				printf("NO\n");
		}
		else
		{
			if(c < d)
				printf("YES\n");
			else
				printf("NO\n");
		}
	}
	return 0;
}

抱歉!评论已关闭.