noip模拟 五子棋

递推+模拟。在读取数据时,我们建4个图,分别代表这个图中横、纵、左斜右斜的连续长度。例如heng[i][j]代表ij这个点所在的横着一条线的长度。

然后搜索,对于一个空点,如果他的上下都>=4那么如果这个点放上去答案会-1,如果上下都<=4且加起来再+1>4,说明这个点放上去会+1.

左右、左上右下、右上左下以此类推。最后如果这个点>=1就输出。

 

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cstring>
#define in(a) a=read();
#define REP(i,k,n)  for(int i=k;i<=n;i++)
using namespace std;
inline int read(){
    int x=0,f=1;
    char ch=getchar();
    for(;!isdigit(ch);ch=getchar())
        if(ch=='-')
            f=-1;
    for(;isdigit(ch);ch=getchar())
        x=x*10+ch-'0';
    return x*f;
}
int n,map[45][45];
int heng[45][45],zong[45][45],zuo[45][45],you[45][45];
int main(){
    freopen("wuzi.in","r",stdin);
    freopen("wuzi.out","w",stdout);
    scanf("%d",&n);
    char c;
    REP(i,1,n)
        REP(j,1,n){
            cin>>c;
            if(c=='*')  map[i][j]=0;
            if(c=='b')  map[i][j]=-1;
            if(c=='w'){
                map[i][j]=1;
                if(i==1 || map[i-1][j]!=1)  zong[i][j]=1;
                if(map[i-1][j]==1)  zong[i][j]=zong[i-1][j]+1;
                if(j==1 || map[i][j-1]!=1)  heng[i][j]=1;
                if(map[i][j-1]==1)  heng[i][j]=heng[i][j-1]+1;
                if(i==1 || j==1 || map[i-1][j-1]!=1)  you[i][j]=1;
                if(map[i-1][j-1]==1)  you[i][j]=you[i-1][j-1]+1;
                if(i==1 || j==n || map[i-1][j+1]!=1)  zuo[i][j]=1;
                if(map[i-1][j+1]==1)  zuo[i][j]=zuo[i-1][j+1]+1;
            }
        }
    for(int i=n;i>=1;i--)
        for(int j=n;j>=1;j--)
            if(map[i][j]==1){
                if(i!=n && zong[i+1][j])  zong[i][j]=zong[i+1][j];
                if(j!=n && heng[i][j+1])  heng[i][j]=heng[i][j+1];
                if(i!=n && j!=n && you[i+1][j+1])  you[i][j]=you[i+1][j+1];
                if(i!=n && j!=1 && zuo[i+1][j-1])  zuo[i][j]=zuo[i+1][j-1]; 
            }
    REP(i,1,n)
        REP(j,1,n)
            if(map[i][j]==0){
                int cnt=0;
                if(zong[i-1][j]>=5 && zong[i+1][j]>=5)  cnt--;
                if(zong[i-1][j]<5 && zong[i+1][j]<5 && zong[i-1][j]+zong[i+1][j]+1>=5)  cnt++;
                if(heng[i][j+1]>=5 && heng[i][j-1]>=5)  cnt--;
                if(heng[i][j+1]<5 && heng[i][j-1]<5 && heng[i][j+1]+heng[i][j-1]+1>=5)  cnt++;
                if(zuo[i-1][j+1]>=5 && zuo[i+1][j-1]>=5)  cnt--;
                if(zuo[i-1][j+1]<5 && zuo[i+1][j-1]<5 && zuo[i-1][j+1]+zuo[i+1][j-1]+1>=5)  cnt++;
                if(you[i-1][j-1]>=5 && you[i+1][j+1]>=5)  cnt--;
                if(you[i-1][j-1]<5 && you[i+1][j+1]<5 && you[i-1][j-1]+you[i+1][j+1]+1>=5)  cnt++;
                if(cnt>0)  cout<<j-1<<" "<<i-1<<endl;
            }        
    return 0;
}

 

posted @ 2018-10-04 14:58  Dijkstra·Liu  阅读(808)  评论(0编辑  收藏  举报