HDU 1079 Calendar Game (博弈或暴搜)
题意:给定一个日期,然后 A 和 B 双方进行操作,谁先把日期变成2001年11月04日,将获胜,如果超过该日期,则输了,就两种操作。
第一种:变成下一天,比如现在是2001.11.3 变成 2001.11.4
第二种,变成下一个月的同一天,比如现在是2001.10.3 变成 2001.11.3,当然有可能是不成立的,比如2001.1.30 不能变成2001.2.30,因为2月没有30天。
析:因为题目中说了是从1990年到2001年,大约100年的时间,也就是400 * 100,完全可以存储下来,或者是直接暴力并且记忆化,这里就是要处理一些特殊情况,比如闰年,下一天跨年了,或者超过2001.11.4了等等,速度还挺快的。
这第二种解法才是正规的解法,要发现这两种情况的共同点,首先把月份和日份看成一个整体,或者是求和sum就好,因为 11+4 = 15,15 是奇数,那么如果开始的日期是偶数,就一定能够获胜,除非有一种日期从能偶数只能变成偶数,很遗憾,并没有这种日期,也就是只要日期是偶数就是一定能够获胜,下面有解释,当然前提是这两个人都足够聪明,那么是不是是奇数就不能胜了?答案不一定,下面慢慢分析,把日期分成三大类,
第一类,变成一个月的同一天,那么如果能变化的话,sum的奇偶性会发生变化,也就是奇变偶,偶变奇
第二类,就成下一天,对于这个仔细点会发现,sum不全是会变化,只有几个是特例,这第二类就是sum会变化的,
第三类,我们细分一下哪几个特例,也就是说下一天,sum不一定会发生变化的,首先就是 2 月 这个特殊的月份,先考虑不是闰年,那么 2 月就只有 28 天,2 + 28 是偶数,我们推理过如果 sum 是偶数,那么就一定能获胜,那么如果是闰年呢,那么 2 月有 29 天,那么是一个奇数,它的一天是 3.1,奇偶性变成了变化,所以不用考虑 2 月了,同理可以解决 4.30 虽然下一个日期是 5.1 也是偶数,但是它本身偶数,所以一定能获胜,6.30 也是,但是有两个特例也就满足这第三类的,9.30 和 11.30 这两个 sum 是奇数,但是它的下一天是是奇数,下一个月是偶数,也就是说奇偶性不一定不发生变化。但是这两个日期一定能获胜,为什么呢,因为当某个玩家到了 9.30 或者是 11.30 ,我们前面考虑过了如果日期是偶数,就能够获胜,所以它肯定是选择变成下一个日期,这样的话,对方就是奇数了,而下次我就是成偶数了。也就是说如果经过 9.30 或者是 11.30 那么奇偶就会发生翻转。那么这和我们前面说的偶数就一定能够获胜好像是矛盾啊,其实不然,因为每个人都是足够聪明的,能够获胜的那个玩家肯定要避免对方能够拿到这个日期,而且完全可以做到举个例子, 9.30 能够到达 9.30 的只有 9.29 或者是 8.30,那么只要 9.29 的变成下一个月,8.30 的变成下一天,就能够避免对方得到这两个日期,也就能够获胜了。同时如果给定一开始给定的就是 9.30 或 11.30 ,那么这个和虽然不是偶数,也是也能获胜,至少为什么,前面已经说了,经过这两个日期,聪明的玩家的可以把奇偶性翻转,并且以后可以避免让对方再得到这两个日期。
综上,如果先手想胜的话,只有二种情况,一种是日份和月份的和是偶数,第二种,就是开始日期就是 9.30 或者是 11.30。
两种不同的解法,代码差的可不是一点,但是思维量也不是同等的
代码如下:
首先先贴上 dfs 记忆化解决 SG 函数的代码
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#include <numeric>
#define debug() puts("++++")
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
//#define all 1,n,1
#define FOR(i,x,n) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.in", "r", stdin)
#define freopenw freopen("out.out", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e17;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1000 + 10;
const int maxm = 100 + 2;
const LL mod = 100000000;
const int dr[] = {-1, 1, 0, 0, 1, 1, -1, -1};
const int dc[] = {0, 0, 1, -1, 1, -1, 1, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r >= 0 && r < n && c >= 0 && c < m;
} bool isLeapYear(int x){
if(x % 400 == 0) return true;
if(x % 100 == 0) return false;
if(x % 4 == 0) return true;
return false;
} int nextDay(int x){
int d = x % 100; x /= 100;
int m = x % 100; x /= 100;
int y = x;
if(isLeapYear(y) ? monn[m] == d : mon[m] == d){
d = 1; ++m;
if(m > 12) m = 1, ++y;
return (y * 100 + m) * 100 + d;
}
return (y * 100 + m) * 100 + d + 1;
} int nextMonth(int x){
int d = x % 100; x /= 100;
int m = x % 100; x /= 100;
int y = x;
if(m == 12) return (y * 100 + 101) * 100 + d;
if(m == 1 && d == 29) return isLeapYear(y) ? (y * 100 + 2) * 100 + d : 0;
if(m == 1 && d > 29) return 0;
if(mon[m+1] < d) return 0;
return (y * 100 + m + 1) * 100 + d;
} map<int, bool> mp;
const int last_date = 20011104; bool dfs(int x){
if(mp.count(x)) return mp[x];
bool &ans = mp[x];
if(x == last_date) return ans = false;
int next = nextDay(x);
if(!dfs(next)) return ans = true;
if((next = nextMonth(x)) && next <= last_date && !dfs(next)) return ans = true;
return ans = false;
} int main(){
int T; cin >> T;
int y, d;
while(T-- && scanf("%d %d %d", &y, &m, &d) == 3){
n = (y * 100 + m) * 100 + d;
if(dfs(n)) puts("YES");
else puts("NO");
}
return 0;
}
下面是正解的代码
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include <cstdio>
#include <string>
#include <cstdlib>
#include <cmath>
#include <iostream>
#include <cstring>
#include <set>
#include <queue>
#include <algorithm>
#include <vector>
#include <map>
#include <cctype>
#include <cmath>
#include <stack>
#include <sstream>
#include <list>
#include <assert.h>
#include <bitset>
#include <numeric>
#define debug() puts("++++")
#define gcd(a, b) __gcd(a, b)
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define fi first
#define se second
#define pb push_back
#define sqr(x) ((x)*(x))
#define ms(a,b) memset(a, b, sizeof a)
#define sz size()
#define pu push_up
#define pd push_down
#define cl clear()
#define lowbit(x) -x&x
//#define all 1,n,1
#define FOR(i,x,n) for(int i = (x); i < (n); ++i)
#define freopenr freopen("in.in", "r", stdin)
#define freopenw freopen("out.out", "w", stdout)
using namespace std; typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> P;
const int INF = 0x3f3f3f3f;
const LL LNF = 1e17;
const double inf = 1e20;
const double PI = acos(-1.0);
const double eps = 1e-8;
const int maxn = 1000 + 10;
const int maxm = 100 + 2;
const LL mod = 100000000;
const int dr[] = {-1, 1, 0, 0, 1, 1, -1, -1};
const int dc[] = {0, 0, 1, -1, 1, -1, 1, -1};
const char *de[] = {"0000", "0001", "0010", "0011", "0100", "0101", "0110", "0111", "1000", "1001", "1010", "1011", "1100", "1101", "1110", "1111"};
int n, m;
const int mon[] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
const int monn[] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
inline bool is_in(int r, int c) {
return r >= 0 && r < n && c >= 0 && c < m;
} int main(){
int T; cin >> T;
while(T--){
int y, d;
scanf("%d %d %d", &y, &m, &d);
if((m+d) % 2 == 0 || m == 9 && d == 30 || m == 11 && d == 30) puts("YES");
else puts("NO");
}
return 0;
}
HDU 1079 Calendar Game (博弈或暴搜)的更多相关文章
- HDU 1079 Calendar Game 博弈
题目大意:从1900年1月1日 - 2001年11月4日间选择一天为起点,两个人依次进行两种操作中的任意一种,当某人操作后为2001年11月4日时,该人获胜.问先手是否获胜 操作1:向后移一天 操作2 ...
- HDU 1079 Calendar Game(简单博弈)
Calendar Game Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- HDU 1079 Calendar Game(规律博弈)
题目链接:https://cn.vjudge.net/problem/HDU-1079 题目: Adam and Eve enter this year’s ACM International Col ...
- HDU 1079 Calendar Game(博弈找规律)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1079 题目大意:给你一个日期(包含年月日),这里我表示成year,month,day,两人轮流操作,每 ...
- HDU 1079 Calendar Game (博弈)
Calendar Game Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
- Hdu 1079 Calendar Game
Problem地址:http://acm.hdu.edu.cn/showproblem.php?pid=1079 一道博弈题.刚开始想用判断P点和N点的方法来打表,但无奈不知是哪里出错,总是WA.于是 ...
- HDU 1079 Calendar Game (博弈论-sg)
版权声明:欢迎关注我的博客,本文为博主[炒饭君]原创文章.未经博主同意不得转载 https://blog.csdn.net/a1061747415/article/details/32336485 C ...
- HDU 4277 USACO ORZ(DFS暴搜+set去重)
原题代号:HDU 4277 原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=4277 原题描述: USACO ORZ Time Limit: 5000/1 ...
- hdu 1079 Calendar Game sg函数 难度:0
Calendar Game Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Tot ...
随机推荐
- AngularJS——第5章 作用域
第5章 作用域 通常AngularJS中应用(App)是由若干个视图(View)组合成而成的,而视图(View)又都是HTML元素,并且HTML元素是可以互相嵌套的,另一方面视图都隶属于某个控制器(C ...
- openCV基础知识
openCV主体分为5个模块: CV图像处理函数和计算机视觉算法: ML机器学习库,包含许多聚类和数据分析函数: HighGUI图像和视频的输入输出: [分成三部分:硬件部分--摄像机;文件部分--载 ...
- mui 注意事项
1>一切内容都要包裹在mui-content中 顶部导航栏(.mui-bar-nav).底部工具条(.mui-bar-footer).底部选项卡(.mui-bar-tab)放在.mui-cont ...
- 移动端 input 输入框实现自带键盘“搜索“功能并修改X
主要利用html5的,input[type=search]属性来实现,此时input和type=text外观和功能没啥区别: html代码入下: <form action="" ...
- poj 2492(关系并查集) 同性恋
题目;http://poj.org/problem?id=2492 卧槽很前卫的题意啊,感觉节操都碎了, t组测试数据,然后n,m,n条虫子,然后m行,每行两个数代表a和b有性行为(默认既然能这样就代 ...
- NGS基础 - 高通量测序原理
NGS基础 - 高通量测序原理 原创: 赑屃 生信宝典 2017-07-23 NGS系列文章包括NGS基础.转录组分析.ChIP-seq分析.DNA甲基化分析.重测序分析五部分内容. NGS基础系列文 ...
- Tinyos学习笔记(二)
1.TinyOS communication tools java serialApp -comm serial@/dev/ttyUSB0:telosb java net.tinyos.tools.L ...
- Java Swing 中使用 EventQueue
public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { ...
- 查看CPU核数和内存
查看CPU核数 top 然后按数字键1 通过虚拟文件系统proc,直接获取CPU总数量 cat /proc/cpuinfo | grep processor 查看内存 free命令主要用于显示内存数量 ...
- Python编程笔记(第二篇)二进制、字符编码、数据类型
一.二进制 bin() 在python中可以用bin()内置函数获取一个十进制的数的二进制 计算机容量单位 8bit = 1 bytes 字节,最小的存储单位,1bytes缩写为1B 1KB = 10 ...