zoukankan      html  css  js  c++  java
  • 2018.10.25-dtoj-3989-五子棋(fir)

    题目描述:

    就像题目名字一样,他们在玩一种类似于五子棋的游戏,只是规则和五子棋有一些不同。 就像五子棋一样,ITer和Kitty依次在棋盘上放置棋子,ITer放置黑子,Kitty放置白子。与五子棋不同的是,当一种颜色的X个棋子组成一行或一列或一个对角线的时候(X不一定等于5),执该颜色的子的玩家胜利。

    如图,当X=5时,ITer胜利的三种方法:

    下了一会儿后,ITer和Kitty觉得无聊了。于是,他们又加了一个类似围棋的规则:当一个连通分量(四连通)的棋子的四周被另一种棋子围住时,这些棋子就消失了,我们称这些子被“吃掉”了。

    如图,三颗白棋的四周都被黑棋围住,所以这三颗棋子就应该消失。成为下图:

    现在ITer和Kitty下了N步棋,ITer先手,每次下棋的位置用坐标表示。 现在ITer想知道,下了N步棋后,是否有人赢了,在第几步赢了,是否有不合法的走法。

    输入:

    输入文件第一行两个正整数N,X,表示下了N步棋,当一种颜色的X个棋子组成一行或一列或一个对角线的时候,执该颜色的子的玩家胜利。 接下来的N行,每行2个正整数Xi,Yi,当i为奇数时,表示ITer在第 i步下在了(Xi,Yi)上,当i为偶数时,表示Kitty在第 i步下在了(Xi,Yi)上。

    输出:

    如果ITer在前N步赢了,则输出“ITer X”(中间用空格连接),X表示ITer在第几步赢了。 如果Kitty在前N步赢了,则输出“Kitty X”(中间用空格连接),X表示Kitty在第几步赢了。 如果在N步以内有不合法的步,则输出“illegal”。

    一步不合法有以下几种情况:
    1. 这步下在了已经有棋子的格子上。
    2. 在没有吃掉对方棋子的情况下,该步子所在的联通分量的棋子被对方的棋子吃掉。如图1,白子走在了红叉的位置上是不合法的,因为这样会使该联通分量被吃掉。

    如图2,如果白子走在红叉的位置上是合法的,因为它吃掉了右边的两个黑子。走完这步后白子不会消失,棋盘上的子变成图3。

    请忽视某一个人赢了以后出现的不合法的步。 如果既没有出现不合法的步,又没有决出胜负,则输出“draw”。 假设棋盘是无限的。

    数据范围:

    Subtask 1 30%:N≤20,X≤5,Xi,Yi≤10。 Subtask 2 70%:N≤1000,X≤10,1≤Xi,Yi≤1000 。

    算法标签:模拟!!

    恨模拟的根源是这道题!铭记了

    思路:

    只要你能想到的暴力都不会T,但我还是调了很久,最后绝望了....气啊....对于连成一条的暴力往两边扩张,看能不能达到个数。每次从当前点向外搜索,先判自己能否成为边界包死别人。再搜一次判断自己会不会被包死。

    以下为调了半下午仍旧只有70+的我的代码(仅作纪念):

    #include<bits/stdc++.h>
    #define il inline
    #define _(d) while(d(isdigit(ch=getchar())))
    using namespace std;
    const int N=1005;int n,st,a[N][N],op,fa[N],mx,my;bool pd,vis[N][N];
    int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
    il int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return f*x;}
    il int getfa(int x){if(!fa[x])return x;return fa[x]=getfa(fa[x]);}
    il bool work(int x,int y,int col){
        if(a[x][y]==3-col)return 1;if(a[x][y]==0)return 0;
        vis[x][y]=1;
        for(int i=0;i<4;i++){
            int xx=dx[i]+x,yy=dy[i]+y;
            if(xx<0||yy<0||xx>mx||yy>my)return 0;
            if(!vis[xx][yy]&&work(xx,yy,col)==0)return 0;
        }
        return 1;
    }
    il void change(int x,int y){
        if(!vis[x][y])return;vis[x][y]=0;a[x][y]=0;
        for(int i=0;i<4;i++){
            int xx=dx[i]+x,yy=dy[i]+y;
            change(xx,yy);
        }
    }
    il void c(int x,int y){
        if(!vis[x][y])return;vis[x][y]=0;
        for(int i=0;i<4;i++){
            int xx=dx[i]+x,yy=dy[i]+y;c(xx,yy);
        }
    }
    int main()
    {
        freopen("123.out","w",stdout);
        n=read();st=read();op=1;
        for(int i=1;i<=n;i++){
            int x=read(),y=read();if(pd)continue;mx=max(mx,x);my=max(my,y);
            if(op==1&&a[x][y]!=0){puts("illegal");pd=1;continue;}
            if(op==2&&a[x][y]!=0){puts("illegal");pd=1;continue;    }
            a[x][y]=op;
            int k=x,res=1;while(k-1>0&&a[k-1][y]==op)res++,k--;
            k=x;while(k+1<=n&&a[k+1][y]==op)res++,k++;
            if(res>=st){
                if(op==1)printf("ITer %d
    ",i);
                if(op==2)printf("Kitty %d
    ",i);
                pd=1;continue;
            }
            res=1;k=y;while(k-1>0&&a[x][k-1]==op)res++,k--;
            k=y;while(k+1<=n&&a[x][k+1]==op)res++,k++;
            if(res>=st){
                if(op==1)printf("ITer %d
    ",i);
                if(op==2)printf("Kitty %d
    ",i);
                pd=1;continue;
            }
            int k1=x,k2=y;res=1;
            while(k1+1<=n&&k2+1<=n&&a[k1+1][k2+1]==op)res++,k1++,k2++;
            k1=x,k2=y;while(k1-1>0&&k2-1>0&&a[k1-1][k2-1]==op)res++,k1--,k2--;
            if(res>=st){
                if(op==1)printf("ITer %d
    ",i);
                if(op==2)printf("Kitty %d
    ",i);
                pd=1;continue;
            }
            for(int i=0;i<4;i++)if(x+dx[i]<=mx&&x+dx[i]>0&&y+dy[i]<=my&&y+dy[i]>0){
                int res=work(x+dx[i],y+dy[i],3-op);if(res==1)change(x+dx[i],y+dy[i]);
                else c(x+dx[i],y+dy[i]);
            }
            if(pdd(x,y))puts("illegal");
            op=3-op;
        }
        if(!pd)puts("draw");
      return 0;
    }
    View Code

    以下为在sgx神犇“援助”下的代码(没耐心本人)

    #include<bits/stdc++.h>
    using namespace std;
    #define il inline
    #define _(d) while(d(isdigit(ch=getchar())))
    const int N=1004;int dx[4]={0,1,0,-1},dy[4]={1,0,-1,0};
    int a[N][N],cnt,n,k,C,id[N][N],mx,my;bool vis[N];
    il int read(){int x,f=1;char ch;_(!)ch=='-'?f=-1:f;x=ch^48;_()x=(x<<1)+(x<<3)+(ch^48);return f*x;}
    il bool J(int r,int x,int y,int col,bool is,int fl){
        vis[id[x][y]]=1;
        bool ff=0;
        for(int i=0;i<4;i++){
            int tx=x+dx[i],ty=y+dy[i];
            if((!a[tx][ty])||(is&&a[tx][ty]==3-col&&(!vis[id[tx][ty]])
            &&(!J(r,tx,ty,3-col,0,0))))ff=1;
        }
        for(int i=0;i<4;i++){
            int tx=x+dx[i],ty=y+dy[i];
            if(a[tx][ty]==col){
                if((!vis[id[tx][ty]])&&J(r,tx,ty,col,is,ff|fl)) ff=1;
            }
        }
        if(ff)return true;
        if(!is&&!(fl|ff)) a[x][y]=0;
        return false;
    } 
    il bool work(int r,int x,int y,int t1,int t2){
        int x1=0,x2=0;
        for(int i=0;i<=k;i++){
            if(a[x+i*t1][y+i*t2]==C)x1++;else break;
        }
        for(int i=0;i<=k;i++){
            if(a[x-i*t1][y-i*t2]==C)x2++;else break;
        }
        if(x1+x2-1>=k){
            if(C==1)printf("ITer %d
    ",r);
            else printf("Kitty %d
    ",r);
            return 0;
        }
        return 1;
    }
    int main(){
        n=read();k=read();C=2;
        for(int i=1;i<=n;i++){
            for(int j=1;j<=n;j++)vis[j]=0;
            C=3-C; int x,y;x=read();y=read();id[x][y]=++cnt;
            if(a[x][y]){puts("illegal");return 0;}
            a[x][y]=C;
            memset(vis,0,sizeof(vis));
            if(!J(i,x,y,C,1,0)){puts("illegal");return 0;}
            mx=max(mx,x);my=max(my,y);
            for(int j=-1;j<=1;j++)for(int l=-1;l<=1;l++){
                if(!j&&!l)continue;
                if(!work(i,x,y,j,l)) return 0;
            }
        }
        puts("draw");
        return 0;
    }
    View Code

    讨厌什么就要让它向你请安!立下爆刷模拟flag

  • 相关阅读:
    硬盘
    vim 使用技巧
    R语言自定义函数中的位置参数、关键字参数、默认参数
    R语言中批量加载函数
    R语言中如何在函数内部定义全局变量
    centos7.9中安装dnf;bash: dnf: command not found...
    ubantu中实现root用户登录ssh
    linux系统中如何修改主机名
    Ubuntu 20.04.2如何root登录
    清北学堂模拟day6 兔子
  • 原文地址:https://www.cnblogs.com/Jessie-/p/9851022.html
Copyright © 2011-2022 走看看