暑期个人赛--第二场--D--every SG(重)
来源:互联网 发布:如何修改淘宝店铺域名 编辑:程序博客网 时间:2024/06/04 19:51
D. 学姐逗学弟 2014新生暑假个人排位赛02
题目描述
学弟们来了之后,学姐每天都非常高兴的和学弟一起玩耍。这一天,学姐想出了这样一个游戏,她画了一棵树,树上共有
输入格式
输入第一行为一个整数
输出格式
如果学姐能胜利,输出"MengMengDa!",否则输出"So sad..."。没有引号。
输入样例
13 11 11
输出样例
MengMengDa!
赛中提交:T T T T
赛后AC:YES
题目大意:
有若干个相同有向图,每个图有n个节点,有m颗石子分布在上面。
每个节点可以放多个石子。
每个人在玩的时候需要移动所有有石子顶点的所有石子(可以移动到不同子节点)
问是否先手必胜。
思路:
直接使用Every-SG的结论。详见国家集训队的论文。
首先,每个节点的移动都可以看做一个独立的游戏,且所有石子都应该移向下一步的最优策略点
因为每轮到一个人操作时,根据结论,都想要将自己必胜的点的结束时刻尽量延后,而必败的点的结束尽量提前
所以这道题的代码的主要思想就是从每一个初始有石子的节点往下遍历搜索,相当于模拟每一轮游戏的所有的走法,
然后从叶子节点处开始回归,对于必胜点(不管是先手后手)找出其后继点的最大步数,必败点也相应找出其后继点的最小步数
最后将每一个有石子节点都计算完了之后,看看谁的必胜点的步数最大,则谁必胜
一下是AC代码
#include "iostream"#include "string.h"#include "stdio.h"#include "stdlib.h"#include "math.h"#include "string"#include "vector"#include "list"#include "map"#include "queue"#include "stack"#include "bitset"#include "algorithm"#include "numeric"#include "functional" using namespace std;vector<int> g[100005];int stone;int step[100005];int dp[100005]; int dfs(int fa){ if(dp[fa]>=0){ return dp[fa]; } else if(g[fa].size()==0){ step[fa]=0; return dp[fa]=0; } int ma=0,mi=99999999; for(int i=0;i<g[fa].size();i+=1){ int son=g[fa][i]; if(dfs(son)==0){ //下一步存在必败态,则当前为必胜态,延长胜利时间 ma=max(step[son],ma); dp[fa]=1; } else{ mi=min(mi,step[son]); //先把最小值也计算出来,等下直接判断后不管什么情况就都可以赋值了 } } if(dp[fa]==1){ step[fa]=ma+1; return 1; } else{ step[fa]=mi+1; return dp[fa]=0; }} int main(){ int T; scanf("%d",&T); while(T--){ int n,m,fa,steps=0,m1,m2; memset(dp,-1,sizeof(dp)); scanf("%d %d",&n,&m); for(int i=2;i<=n;i+=1){ scanf("%d",&fa); g[fa].push_back(i); } m1=0,m2=0; for(int i=0;i<m;i+=1){ scanf("%d",&stone); if(dfs(stone)){ m1=max(m1,step[stone]); //dfs为1时先手必胜,此时为其更新最大值 } else{ m2=max(m2,step[stone]); //dfs为0时后手必胜,此时为其更新最大值 } } if(m1>m2){ //谁的所有必胜态中的步数最大谁赢 printf("MengMengDa!\n"); } else{ printf("So sad...\n"); } for(int i=0;i<=n+1;i+=1){ g[i].clear(); } } return 0;}
- 暑期个人赛--第二场--D--every SG(重)
- 暑期个人赛--第二场--D
- 暑期个人赛第二场
- 暑期个人赛--第二场--A
- 暑期个人赛--第二场--B
- 暑期个人赛--第二场--C
- 暑期个人赛--第四场--D(待A)
- 暑期个人赛--第一场--D
- 暑期个人赛--第五场--D
- 暑期个人赛--第三场--D
- 暑期个人赛--第八场--D
- 暑期个人赛--第六场--D(包含手写邻接链表模板~!!)
- 暑期个人赛--第七场--D(复习~!含静态邻接链表)
- 暑期个人赛第一场
- 暑期个人赛--第六场--B(常复习~!!!)
- 暑期个人赛--第三场--E(待A)
- 暑期个人赛--第三场--E(待A....)
- 暑期个人赛--第四场--E(待A)
- Oracle 常用的函数小结
- LeetCode OJ算法题(三十一):Longest Valid Parentheses
- PHP转换文件夹下所有文件编码的实现代码(转)
- Eclipse 新建PHP工程教程
- C++中的纯虚函数
- 暑期个人赛--第二场--D--every SG(重)
- Codeforces 451C Predict Outcome of the Game(暴力)
- Linux TCP/UDP小例子
- Spring和Hibernate集成的HibernateTemplate的一些常用方法总结
- OpenCV的三帧差法
- 重载(overload)、覆盖(override)、隐藏(hide)的区别
- HD 2013 蟠桃记
- rman做异机迁移
- VF