zoukankan      html  css  js  c++  java
  • [Wc]Dface双面棋盘

    题目

    bzoj1453

    题解

    不算正解吧,数据不是很严,所以过掉了

    很容易想到暴力做法,每次翻转后重新算一遍联通块个数,复杂度O(n²m),但实际上每次翻转后只有与之相邻的联通块会发生变化,其余地方均无改变,会造成许多重复的计算

    考虑每次翻转后只对相邻联通块进行修改,用bfs直接搜(dfs超时)

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cmath> 
    #include <queue>
    #define ll long long
    using namespace std; 
     
    int n,m,mp[210][210],ans[2];
    int fx[]={0,0,0,-1,1};
    int fy[]={0,1,-1,0,0};
    bool flag[210][210];
    int X,Y; 
     
    struct node
    {
        int x,y;
    };
     
    void bfs(int x,int y,int f)
    {   
        queue<node> q; 
        flag[x][y]=1;
        node t;t.x=x;t.y=y;
        q.push(t);
        while(!q.empty())
        {
            node p=q.front();
            q.pop();
            for(int i=1;i<=4;i++)
            {
                int xx=p.x+fx[i],yy=p.y+fy[i];
                if(xx>=1&&xx<=n&&yy>=1&&yy<=n)
                    if(mp[p.x][p.y]==mp[xx][yy]&&!flag[xx][yy])
                    {
                        flag[xx][yy]=1;
                        t.x=xx;t.y=yy;
                        q.push(t);
                    } 
            }
            if(f)
            {
                if(X+1<=n) if(!flag[X+1][Y]&&mp[X+1][Y]==mp[x][y]) continue;
                if(X-1>=1) if(!flag[X-1][Y]&&mp[X-1][Y]==mp[x][y]) continue;
                if(Y+1<=n) if(!flag[X][Y+1]&&mp[X][Y+1]==mp[x][y]) continue;
                if(Y-1>=1) if(!flag[X][Y-1]&&mp[X][Y-1]==mp[x][y]) continue;
                return;
            }
        }
    }
     
    int gcd(int x,int y)
    {
        if(!y) return x;
        gcd(y,x%y);
    }
     
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++) scanf("%d",&mp[i][j]);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
            if(!flag[i][j]) {bfs(i,j,0);ans[mp[i][j]]++;}
        scanf("%d",&m);
        for(int i=1;i<=m;i++)
        {
            int x,y;scanf("%d%d",&x,&y);
            memset(flag,0,sizeof(flag));
            X=x;Y=y;
            for(int k=0;k<=4;k++)
            {
                int xx=x+fx[k],yy=y+fy[k];
                if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&!flag[xx][yy])
                    {bfs(xx,yy,1);ans[mp[xx][yy]]--;}
            }
            mp[x][y]^=1; 
            memset(flag,0,sizeof(flag));
            for(int k=0;k<=4;k++)
            {
                int xx=x+fx[k],yy=y+fy[k];
                if(xx>=1&&xx<=n&&yy>=1&&yy<=n&&!flag[xx][yy])
                    {bfs(xx,yy,1);ans[mp[xx][yy]]++;}
            }
            printf("%d %d
    ",ans[1],ans[0]);
            /*
            if(ans[0]==0||ans[1]==0) {printf("-1
    ");continue;}
            int g=gcd(ans[1],ans[0]);
            if(ans[0]/g==1) {printf("%d
    ",ans[1]/g);continue;}
            printf("%d/%d
    ",ans[1]/g,ans[0]/g);
            */
        }
        return 0;
    }
  • 相关阅读:
    计算机网络笔记6-应用层
    计算机网络笔记5-传输层
    计算机网络笔记4-网络层
    计算机组成原理笔记7-输入输出系统
    计算机组成原理笔记6-总线
    计算机组成原理笔记5-中央处理器
    计算机网络笔记3-数据链路层
    计算机组成原理笔记4-指令系统
    计算机组成原理笔记3-存储系统
    信息安全数学基础笔记
  • 原文地址:https://www.cnblogs.com/XYZinc/p/7405338.html
Copyright © 2011-2022 走看看