F - Matches Game
博弈
Nim游戏
概括来说就是寻找必败态
1、问题模型:有三堆各若干个物品,两个人轮流从某一堆取人一多的物品,规定每次至少取一个,多者不限,最后取光者得胜。
2、解决思路:
用(a,b,c)表示某种局势,显然(0,0,0)是第一种局势,无论谁面对奇异局势,都必然失败。
第二种是(0n,n),只要与对手拿走一样多的物品,最后都将导致(0,0,0)。
搞定这个问题必须把必败态炸出:(a,b,c)是必败态等价于a ^ b ^ c==0(^表示异或运算)
3、推广:
如果我们面对的是一个非奇异局势(a,b,c),那么如何变成奇异局势呢?
假设a<b<c,我们只要将c变成a ^ b即可,因为a ^ b ^(a ^ b)=(a ^ a) ^ (b ^ b)=0 ^ 0=0。要将c变成a ^ b,只要c-(a ^ b)。
#include<cmath>
#include <cstdio>
#include <cstring>
#include<iostream>
#include <algorithm>
using namespace std;
int n,ans,a;
int main() {
while(~scanf("%d",&n)) {
ans=0;
while(n--) {
scanf("%d",&a);
ans^=a;
}
printf("%s\n",ans==0?"No":"Yes");
}
return 0;
}
D - Packets
题意是给边长为1~6的正方形,装入6*6的模具中,求最少需要多少个这样的模具。
贪心,每次将当前所剩最大的正方形装入,然后将空余的部分用小正方形填满。
#include<cmath>
#include <cstdio>
#include <cstring>
#include<iostream>
#include <algorithm>
#define N 10
using namespace std;
int a[N];
inline void reset(){
if (a[1]<0) a[1]=0;
}
int read(){
int num=0;
for (int i=1;i<=6;i++)
{
scanf("%d",&a[i]);
num+=a[i];
}
return num;
}
int solve(){
int ans = a[6];
while(a[5]>0)
{
a[5]--;
a[1]-=11;
reset();
ans++;
}
while(a[4]>0)
{
a[4]--;
if (a[2]>=5) a[2]-=5;
else {
a[1]-=(5-a[2])*4;
a[2]=0;
reset();
}
ans++;
}
ans+=a[3]/4;
a[3]%=4;
if (a[3]>0) ans++;
if (a[3]==3)
{
if (a[2]>0) --a[2],a[1]-=5;
else a[1]-=9;
reset();
}
if (a[3]==2)
{
if (a[2]>=3) a[2]-=3,a[1]-=6;
else a[1]-=(6+4*(3-a[2])),a[2]=0;
reset();
}
if (a[3]==1)
{
if (a[2]>=5) a[2]-=5,a[1]-=7;
else a[1]-=(7+4*(5-a[2])),a[2]=0;
reset();
}
if (a[2]>0)
{
ans+=a[2]/9;
a[2]%=9;
if (a[2]) ans++;
a[1]-=(9-a[2])*4;
reset();
}
if (a[1]>0) ans+=a[1]/36;
a[1]%=36;
if (a[1]>0) ans++;
return ans;
}
int main() {
while(read())
{
printf("%d\n",solve());
}
return 0;
}
C - Xiangqi
模拟。
给一个将军的局面,判断这是不是一个死局。
模拟题一定要考虑到所有可能的情况(黑将有可能吃掉红方的棋子。
模拟将能走到的地方(不能斜着走),然后判断红色棋子能否走到即可)
//有bug
#include<cmath>
#include <cstdio>
#include <cstring>
#include<iostream>
#include <algorithm>
#define N 11
using namespace std;
struct node{
int x,y;
char p;
}red[50];
int board[N][N],mp[N][N];
int n,bx,by,rx,ry;
inline int read(){
scanf("%d%d%d",&n,&bx,&by);
for(int i=1;i<=n;i++)
{
cin>>red[i].p>>red[i].x>>red[i].y;
mp[red[i].x][red[i].y] = red[i].p;
if (red[i].p == 'G') rx=red[i].x,ry=red[i].y;
}
return n+bx+by;
}
inline void judge(){
int flag=0;
for (int i = bx+1; i < rx; i++)
if (mp[i][ry]>0) flag=1;
if (!flag) for (int i=1;i<=3;i++) board[i][ry]=1;
}
inline void check(){
if (bx==1&&by==4)
{
if (board[1][5]&&board[2][4]) printf("YES\n");
else printf("NO\n");
}
if (bx==1&&by==5)
{
if (board[1][4]&&board[1][6]&&board[2][5]) printf("YES\n");
else printf("NO\n");
}
if (bx==1&&by==6)
{
if (board[1][5]&&board[2][6]) printf("YES\n");
else printf("NO\n");
}
if (bx==2&&by==4)
{
if (board[1][4]&&board[3][4]&&board[2][5]) printf("YES\n");
else printf("NO\n");
}
if (bx==2&&by==5)
{
if (board[2][4]&&board[2][6]&&board[1][5]&&board[3][5]) printf("YES\n");
else printf("NO\n");
}
if (bx==2&&by==6)
{
if (board[1][6]&&board[3][6]&&board[2][5]) printf("YES\n");
else printf("NO\n");
}
if (bx==3&&by==4)
{
if (board[2][4]&&board[3][5]) printf("YES\n");
else printf("NO\n");
}
if (bx==3&&by==5)
{
if (board[3][4]&&board[3][6]&&board[2][5]) printf("YES\n");
else printf("NO\n");
}
if (bx==3&&by==6)
{
if (board[2][6]&&board[3][5]) printf("YES\n");
else printf("NO\n");
}
}
int main(){
while(read())
{
judge();
for (int i=1;i<=n;i++)
{
if (red[i].p=='R')
{
for (int j=1;j<=10;j++) board[j][red[i].y]=1;
for (int j=1;j<=9;j++) board[red[i].x][j]=1;
}
if (red[i].p=='C')
{
for (int j=red[i].x-1;j>=1;j--)
if (board[j][red[i].y]>1)
{
for (int k=j-1;k>=1;k--) board[k][red[i].y]=1;
break;
}
}
if(red[i].p=='H')
{
int tx=red[i].x,ty=red[i].y;
if (tx-1>0 && ty-2>0 && !mp[tx][ty-1]) board[tx-1][ty-2]=1;
if (tx+1<=10 && ty-2>0 && !mp[tx][ty-1]) board[tx+1][ty-2]=1;
if (tx-2>0 && ty-1>0 && !mp[tx-1][ty]) board[tx-2][ty-1]=1;
if (tx-2>0 && ty+1<=9 && !mp[tx-1][ty]) board[tx-2][ty+1]=1;
if (tx-1>0 && ty+2<=9 && !mp[tx][ty+1]) board[tx-1][ty+2]=1;
if (tx+1<=10 && ty+2<=9 && !mp[tx][ty+1]) board[tx+1][ty+2]=1;
if (tx+2<=10 && ty-1>0 && !mp[tx+1][ty]) board[tx+2][ty-1]=1;
if (tx+2<=10 && ty+1<=9 && !mp[tx+1][ty]) board[tx+2][ty+1]=1;
}
}
check();
memset(board,0,sizeof board);
memset(mp,0,sizeof mp);
}
return 0;
}