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