题目
题目B:博弈论---->小念和氧气少年在玩一个关于糖果的游戏,游戏规则如下:一堆糖果有 n 枚,两人可以轮流取糖果,小念先手,氧气少年后手,取走最后一个糖果的人输掉比赛。如果当前这一轮剩余 1 个糖果,那么当前这一轮最少可以取走 1个,最多可以取走 min(x,m)个。为了让游戏更加好玩,他们加入了一个新规则:他们在游戏开始前掷一个硬币,如果掷出正面,则小念得到一次“连取”机会,否则氧气少年得到一次“连取”机会。
得到"连取"机会的人可以选择在任意一次轮到自己的时候连续取两次,当然也可以选择放弃这个机会。
请判断谁会取得胜利。
做法:把特殊情况特判了,然后看谁有可以连续取的机会谁就赢,因为1如果已经是必胜局面可以不用这次机会2如果是必败局面则用了这次机会就是必胜局面
#include<iostream>
using namespace std;
int main()
{
int T;cin>>T;
while(T--)
{
int n,m,p;
cin>>n>>m>>p;
if(n==1)
{
cout<<"YangQiShaoNian\n";
continue;
}
else if(n-m==1||m>=n)
{
cout<<"XiaoNian\n";
continue;
}
if(p==0)cout<<"XiaoNian\n";
else cout<<"YangQiShaoNian\n";
}
}
题目C:题目大意是有一排的水滴,题会给某一滴的饱和度+1,当它的饱和度为10时,会向两边散开,1.如果某一边有水滴则该边的该水滴的饱和度+1,当达到了10则会向两边散开.....以次类推。2.如果某一边没有了水滴,则会向L无穷和R无穷散去,最终让你计算L,R无穷各有多少个
做法:我们可以先首判这个+1的饱和度等于10,如果不等于10则不会发生任何事件,直接结束,如果达到了10则维护一个L,R的区间就好了
#include<iostream>
using namespace std;
const int N = 2e5+10;
int a[N];
int main()
{
ios::sync_with_stdio(0); cin.tie(0);
int T;cin>>T;
while(T--)
{
int n;cin>>n;
int pos;cin>>pos;
for(int i=1;i<=n;i++)cin>>a[i];
if(a[pos]!=9)//不会发生传递事件
{
cout<<0<<' '<<0<<endl;
continue;
}
int l=1,r=1;//初始
int ll=pos-1,rr=pos+1;//从当前向两边枚举数组下标
while(ll>=1||rr<=n)
{
if(ll>=1)
{
if(a[ll]+l>=10)
{
l-=10-a[ll];
r++;
l++;
ll--;
continue;
}
}
if(rr<=n)
{
if(a[rr]+r>=10)
{
r-=10-a[rr];
r++;
l++;
rr++;
continue;
}
}
break;//这里break用的很妙!只要到了这一就説明当前及以后不会发生传递事件
}
if(ll>=1)l=0;
if(rr<=n)r=0;
cout<<l<<' '<<r<<endl;
}
return 0;
}
(差不点写出来,不难的这一题,考虑的少了)