zoukankan      html  css  js  c++  java
  • Codeforces Round #290 (Div. 2) _B找矩形环的三种写法

    http://codeforces.com/contest/510/status/B

    题目大意 给一个n*m  找有没有相同字母连起来的矩形串

    第一种并查集 瞎搞一下

    第一次的时候把val开成字符串了 所以wa

    改了AC

    #include<cstdio>
    #include<map>
    //#include<bits/stdc++.h>
    #include<vector>
    #include<stack>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<set>
    #include<queue>
    #include<cstdlib>
    #include<climits>
    #define PI acos(-1.0)
    #define INF 0x3fffffff
    using namespace std;
    typedef long long ll;
    typedef __int64 int64;
    const ll mood=1e9+7;
    const int64 Mod=998244353;
    const double eps=1e-9;
    const int N=100;
    const int MAXN=1e4+5;
    typedef int rl;
    inline void r(rl&num){
        num=0;rl f=1;char ch=getchar();
        while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
        while(ch>='0'&&ch<='9')num=num*10+ch-'0',ch=getchar();
        num*=f;
    }
    char ch[N][N];
    int  val[N][N];
    int par[MAXN],sum[MAXN];
    int n,m;
    char tem;
    int dx[]={1,0},dy[]={0,1};
    void init()
    {
        int s=0;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
    
                val[i][j]=s;//cout<<val[i][j]<<endl;
                par[s]=s;
                sum[s]=1;
                s++;
            }
        }
    }
    int find(int x)
    {
        if(x==par[x]) return x;
        return par[x]=find(par[x]);
    }
    bool unite(int x,int y)
    {
        x=find(x);y=find(y);
        if(x==y&&sum[x]>=4) return true;
        if(x==y) return false;
        par[x]=y;
        sum[y]+=sum[x];
        return false;
    }
    bool check(int x,int y)
    {
        if(x>=0&&x<n&&y<m&&y>=0&&ch[x][y]==tem) return true;
        else return false;
    }
    int main()
    {
        r(n);r(m);
        for(int i=0;i<n;i++)
        {
            scanf("%s",ch[i]);
        }
        init();
        bool mk=false;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                tem=ch[i][j];
                for(int k=0;k<2;k++)
                {
                    int x=dx[k]+i,y=dy[k]+j;
                    if(check(x,y))
                    {
                        if(unite(val[i][j],val[x][y]))
                        {
                            mk=true;
                            break;
                        }
                    }
                }
                if(mk) break;
            }
            if(mk) break;
        }
        if(mk) puts("Yes");
        else puts("No");
        return 0;
    }
    /*
    50 50
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    XYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXYXY
    */
    并查集

    这个类似联通块 dfs做 首尾相交就输出YES 做一下

    #include<cstdio>
    char ch[52][52];
    int vis[52][52];
    int flag;
    int n,m;
    int dx[]={0,0,-1,1},dy[]={1,-1,0,0};
    void dfs(int atx,int aty,int x,int y,char z)
    {
        if(vis[x][y])
        {
            flag=1;
            return ;
        }
        vis[x][y]=1;
        int nx,ny;
        for(int i=0;i<4;i++)
        {
            nx=x+dx[i];ny=y+dy[i];
            if(nx<0||nx>=n||ny<0||ny>=m||z!=ch[nx][ny]||(atx==nx&&ny==aty)) continue;
            dfs(x,y,nx,ny,z);
        }
        return ;
    }
    int main()
    {
        scanf("%d%d",&n,&m);
        for(int i=0;i<n;i++)
        {
            scanf("%s",ch[i]);
        }
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
            {
                if(!vis[i][j])
                {
                    dfs(-1,-1,i,j,ch[i][j]);
                }
                if(flag){printf("Yes
    ");return 0;}
            }
        printf("No
    ");
        return 0;
    }
    其实dfs做的很不顺利

    还有一个方法 构成矩形块的充要条件 自己的上下左右要有和自己相同的块至少两个 小于两个的块必然不是 可以标记扔掉 

    这里感叹下高手对细节的处理真的好强 等自己写的时候才知道问题在哪里 仔细看下人家的才恍然大悟 这样才不会越界

    就是在n*m的周围搞上一圈空

    大致意思就是把不符合的点全部标记并回到1,2点并不是回到起点 1,1点如果满足条件没被标记的话 就会留下1,1点 所以判断ans>1

    #include<cstdio>
    char ch[52][52];
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            getchar();
            for(int j=1;j<=m;j++)
            {
                ch[i][j]=getchar();
            }
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                if(ch[i][j]!='%')
                {
                     int tem=0;
                    if(ch[i][j]==ch[i-1][j]) tem++;
                    if(ch[i][j]==ch[i+1][j]) tem++;
                    if(ch[i][j]==ch[i][j-1]) tem++;
                    if(ch[i][j]==ch[i][j+1]) tem++;
                    if(tem<2) {ch[i][j]='%';i=j=1;} //回到起点
                }
            }
            int ans=0;
          for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                if(ch[i][j]!='%') ans++;
                if(ans>1)
                {
                    puts("Yes");
                    return 0;
                }
            }
            puts("No");
            return 0;
    }
    神奇的姿势

    现在搞一下回到起点的 只要判断有点留下 那么就输出Yes;

    #include<cstdio>
    char ch[52][52];
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
        {
            getchar();
            for(int j=1;j<=m;j++)
            {
                ch[i][j]=getchar();
            }
        }
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                if(ch[i][j]!='%')
                {
                    int tem=0;
                    if(ch[i][j]==ch[i-1][j]) tem++;
                    if(ch[i][j]==ch[i+1][j]) tem++;
                    if(ch[i][j]==ch[i][j-1]) tem++;
                    if(ch[i][j]==ch[i][j+1]) tem++;
                    if(tem<2) {ch[i][j]='%';i=1;j=0;}
    
                }
            }
            int ans=0;
          for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
            {
                if(ch[i][j]!='%') 
                {
                    puts("Yes");
                    return 0;
                }
            }
            puts("No");
            return 0;
    }
    理解版神奇的姿势
  • 相关阅读:
    计算机专业找工作注意什么
    LU分解
    HDU2050
    牛牛与字符串border 题解(gcd)
    牛牛与交换排序 题解(双端队列模拟区间反转)
    动态最小生成树 题解(线段树+归并排序)
    系数 题解(lucas+思维)
    D. Dogeforces 题解(并查集+构造)
    Java 入土基础
    E. AZ Graph 题解(思维)
  • 原文地址:https://www.cnblogs.com/Geek-xiyang/p/5351506.html
Copyright © 2011-2022 走看看