E. 小L的井字棋
题目简介:
小L和炸鸡在下井字棋。
现给出一个井字棋残局,保证此时棋盘上双方落子数量相同,且还未分出胜负。
现在,轮到小L行动了,由于小L是新手,炸鸡自大地给予了小L一个特权:在接下去的某一次行动中可以连续走两步。 问小L是否有必胜的策略
思路:
通过观察不难发现
- 若当前双方都没有下棋或各下一枚棋或各下两枚棋,则小L一定必胜
- 若当前双方各下四枚棋,直接填入后判断即可。
- 若当前双方各下三枚棋,枚举剩下三种下法,因为小L先手且小L拥有特权,所以剩下三种情况只要有一种必胜,则本局就必胜
代码如下
#include<bits/stdc++.h>
using namespace std;
int t;
char c[5][5];
bool check()
{
if(c[1][1]=='X'&&c[1][2]=='X'&&c[1][3]=='X') return true;
if(c[2][1]=='X'&&c[2][2]=='X'&&c[2][3]=='X') return true;
if(c[3][1]=='X'&&c[3][2]=='X'&&c[3][3]=='X') return true;
if(c[1][1]=='X'&&c[2][1]=='X'&&c[3][1]=='X') return true;
if(c[1][2]=='X'&&c[2][2]=='X'&&c[3][2]=='X') return true;
if(c[1][3]=='X'&&c[2][3]=='X'&&c[3][3]=='X') return true;
if(c[1][1]=='X'&&c[2][2]=='X'&&c[3][3]=='X') return true;
if(c[1][3]=='X'&&c[2][2]=='X'&&c[3][1]=='X') return true;
return false;
}
int main()
{
cin>>t;
while(t--)
{
int cnt=0;
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
{
cin>>c[i][j];
if(c[i][j]!='G') cnt++;
}
if(cnt==8)
{
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
if(c[i][j]=='G') c[i][j]='X';
if(check()) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
else if(cnt==6)
{
bool flag=false;
int cnt=0;
pair<int,int> p[4];
for(int i=1;i<=3;i++)
for(int j=1;j<=3;j++)
if(c[i][j]=='G')
p[++cnt]={i,j};
c[p[1].first][p[1].second]='X';
c[p[2].first][p[2].second]='X';
c[p[3].first][p[3].second]='O';
if(check()) flag=true;
c[p[1].first][p[1].second]='X';
c[p[2].first][p[2].second]='O';
c[p[3].first][p[3].second]='X';
if(check()) flag=true;
c[p[1].first][p[1].second]='O';
c[p[2].first][p[2].second]='X';
c[p[3].first][p[3].second]='X';
if(check()) flag=true;
if(flag) cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
else cout<<"Yes"<<endl;
}
return 0;
}
I. 小L的数学题
题目简介:
给定两个数字, 和
,问能否仅通过任意次的 开方(向下取整) 和 二倍 操作,将
转化为
。
思路:
通过观察不难发现,若 且
,则直接输出
,若
或
(不同时为0)时,不能将
转化为
,否则,任意两个正整数都可以相互转化
代码如下
#include<bits/stdc++.h>
using namespace std;
int t,n,m;
int main()
{
cin>>t;
while(t--)
{
cin>>n>>m;
if(n==0&&m==0) cout<<"Yes"<<endl;
else if(n==0||m==0) cout<<"No"<<endl;
else cout<<"Yes"<<endl;
}
return 0;
}