Xuzhou Winter Camp 1补题

12 篇文章 0 订阅
1 篇文章 0 订阅

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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值