Calendar Game

Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 2766    Accepted Submission(s): 1594

Problem Description
Adam and Eve enter this year’s ACM International Collegiate Programming Contest. Last night, they played the Calendar Game, in celebration of this contest. This game consists of the dates from January 1, 1900 to November 4, 2001, the contest day. The game starts by randomly choosing a date from this interval. Then, the players, Adam and Eve, make moves in their turn with Adam moving first: Adam, Eve, Adam, Eve, etc. There is only one rule for moves and it is simple: from a current date, a player in his/her turn can move either to the next calendar date or the same day of the next month. When the next month does not have the same day, the player moves only to the next calendar date. For example, from December 19, 1924, you can move either to December 20, 1924, the next calendar date, or January 19, 1925, the same day of the next month. From January 31 2001, however, you can move only to February 1, 2001, because February 31, 2001 is invalid.

A player wins the game when he/she exactly reaches the date of November 4, 2001. If a player moves to a date after November 4, 2001, he/she looses the game.

Write a program that decides whether, given an initial date, Adam, the first mover, has a winning strategy.

For this game, you need to identify leap years, where February has 29 days. In the Gregorian calendar, leap years occur in years exactly divisible by four. So, 1993, 1994, and 1995 are not leap years, while 1992 and 1996 are leap years. Additionally, the years ending with 00 are leap years only if they are divisible by 400. So, 1700, 1800, 1900, 2100, and 2200 are not leap years, while 1600, 2000, and 2400 are leap years.

 
Input
The input consists of T test cases. The number of test cases (T) is given in the first line of the input. Each test case is written in a line and corresponds to an initial date. The three integers in a line, YYYY MM DD, represent the date of the DD-th day of MM-th month in the year of YYYY. Remember that initial dates are randomly chosen from the interval between January 1, 1900 and November 4, 2001. 
 
Output
Print exactly one line for each test case. The line should contain the answer "YES" or "NO" to the question of whether Adam has a winning strategy against Eve. Since we have T test cases, your program should output totally T lines of "YES" or "NO". 
 
Sample Input
3
2001 11 3
2001 11 2
2001 10 3
 
Sample Output
YES
NO
NO

思路:sg打表,为了不爆栈从高往低打表,注意日期转换

经验教训:代码风格太凌乱了导致没发现bug

#include <cstdio>
#include <cstring>
using namespace std;
int dayofmonth[12]={31,28,31,30,31,30,31,31,30,31,30,31};
int sg[45000];//记录结果
bool isgapyear(int year){//是否间隔年
if(year%4==0&&(year%100!=0||year%400==0))return true;
return false;
}
int getdofm(int year,int month){//得到这个月天数
int ans=dayofmonth[month];
if(month==1&&isgapyear(year))ans++;
return ans;
}
int getdate(int year,int month,int day){//得到从1970.1.1开始的天数
int date=0;
for(int i=1900;i<year;i++)date+=(isgapyear(i)?366:365);
for(int i=0;i<month;i++){
date+=getdofm(year,i);
}
date+=day;
return date;
}
void getcalendar(int date ,int& year,int &month,int &day){//由从1970开始的天数得到年月日
int accu=0;
for(int i=0;i<102;i++){
accu+=(isgapyear(i+1900)?366:365);
if(date<accu){
year=i;date-=accu-(isgapyear(i+1900)?366:365);break;
}
else if(date==accu){
year=i;day=31;month=11;return ;
}
}
accu=0;
for(int i=0;i<12;i++){
int dm=getdofm(year+1900,i);
accu+=dm;
if(accu>date){
month=i;
date-=accu-dm;
break;
}
else if(accu==date){
month=i;
date=dm;
break;
}
}
day=date;
}
int seg(int date){//sg函数
if(sg[date]!=-1)return sg[date];
int year,month,day;
getcalendar(date,year,month,day);
if(seg(date+1)==0)return sg[date]=1;//日历左移
int ty,tm,td;getcalendar(date+getdofm(year+1900,month),ty,tm,td);
if((day==td&&date+getdofm(year+1900,month)<=37198)&&seg(date+getdofm(year+1900,month))==0)return sg[date]=1;//如果日历下一个月存在这一天,试着移一个月
return sg[date]=0;
}
int main(){
memset(sg,-1,sizeof(sg));
sg[37198]=0;
for(int i=37197 ;i>0;i--){
seg(i);
}
int y,m,d;
int T;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&y,&m,&d);m--;
int date=getdate(y,m,d);
printf("%s\n",seg(date)==0?"NO":"YES");
}
return 0;
}

  

hdu 1079 Calendar Game sg函数 难度:0的更多相关文章

  1. hdu 1536&&1944 S-Nim sg函数 难度:0

    S-Nim Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  2. hdu 3032 Nim or not Nim? sg函数 难度:0

    Nim or not Nim? Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)T ...

  3. hdu 3032(博弈sg函数)

    题意:与原来基本的尼姆博弈不同的是,可以将一堆石子分成两堆石子也算一步操作,其它的都是一样的. 分析:由于石子的堆数和每一堆石子的数量都很大,所以肯定不能用搜索去求sg函数,现在我们只能通过找规律的办 ...

  4. HDU 5724 Chess(SG函数+状态压缩)

    http://acm.split.hdu.edu.cn/showproblem.php?pid=5724 题意: 现在有一个n*20的棋盘,上面有一些棋子,双方每次可以选择一个棋子把它移动到其右边第一 ...

  5. HDU 1079 Calendar Game (博弈或暴搜)

    题意:给定一个日期,然后 A 和 B 双方进行操作,谁先把日期变成2001年11月04日,将获胜,如果超过该日期,则输了,就两种操作. 第一种:变成下一天,比如现在是2001.11.3 变成 2001 ...

  6. HDU 5724 Chess(SG函数)

    Chess Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)Total Submi ...

  7. HDU 1535 S-Nim(SG函数)

    S-Nim Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submi ...

  8. HDU 1079 Calendar Game (博弈论-sg)

    版权声明:欢迎关注我的博客,本文为博主[炒饭君]原创文章.未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/32336485 C ...

  9. hdu 1517 A Multiplication Game 段sg 博弈 难度:0

    A Multiplication Game Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Ot ...

随机推荐

  1. Error: registers may not be the same -- `strexb r3,r2,[r3]'

    tmp\ccFziEge.s:914: Error: registers may not be the same -- `strexb r3,r2,[r3]'tmp\ccFziEge.s:968: E ...

  2. The 15th UESTC Programming Contest Preliminary M - Minimum C0st cdoj1557

    地址:http://acm.uestc.edu.cn/#/problem/show/1557 题目: Minimum C0st Time Limit: 3000/1000MS (Java/Others ...

  3. BitmapFactory.decodeStream(inputStream)返回null的解决方法

    场景:Android,通过inputStream从网络上获取图片 随后两次使用BitmapFactory对InputStream进行操作,一次获取宽高,另一次缩放 但是在缩放时,发现inputStre ...

  4. java并发内存模型

    java中线程之间的共享变量存储在主内存(java堆)中,每个线程都有一个私有的本地内存,本地内存存储了该线程以读.写共享变量的副本.本地内存是一个抽象概念,并不真实存储.它涵盖了cache,寄存器记 ...

  5. Rsync结合Inotify 实时同步配置(更新之前繁琐的传输认证)

    今天一位CU的友友根据之前介绍过 通过rsync+inotify-tools+ssh实现触发式远程实时同步  配置分发系统,但是由于认证繁琐,很容易出错,我今天重新整理了下,用rsync密码文件pas ...

  6. 一键安装lnmp(2)

    all(){path=`pwd`cd $pathechoecho "exclude=*.i386 *.i686" >> /etc/yum.confrpm -ivh ht ...

  7. Android中C可执行程序编译问题

    make:进入目录'/opt/FriendlyARM/tiny4412/android/android-4.1.2'make: *** 没有规则可以创建“out/target/product/gene ...

  8. openssl 编译

    不要费事编译了,直接下载吧! https://www.npcglib.org/~stathis/blog/precompiled-openssl/ 下载 openssl https://www.ope ...

  9. Redis中RedisTemplate和Redisson管道的使用

    当对Redis进行高频次的命令发送时,由于网络IO的原因,会耗去大量的时间.所以Redis提供了管道技术,就是将命令一次性批量的发送给Redis,从而减少IO. 一.Jedis对redis的管道进行操 ...

  10. ThreadPoolExecutor源码浅析

    目录 初始化 ctl变量 添加任务 addWorker方法 worker实现 执行任务 关闭连接池 参考 初始化 ThreadPoolExecutor重载了多个构造方法,不过最终都是调用的同一个: p ...