• HDU 5652 India and China Origins(二分+并查集||BFS)


    http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=682&pid=1003

    中文题意,不再描述。

    题解:

      顺序给山峰出现的时间,明显地用二分来查找。然后连通块用并查集(也可以BFS,复杂度都是O(n))来维护。

    1.并查集

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    using namespace std;
    const int maxn=505;
    char maze[maxn][maxn];
    bool vis[maxn][maxn];
    int n,m,q,par[maxn*maxn];
    int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
    struct node
    {
        int x,y;
    }p[maxn*maxn];
    int find(int x)
    {
        return x==par[x]?x:par[x]=find(par[x]);
    }
    void unite(int x,int y)
    {
        x=find(x);
        y=find(y);
        if(x==y)
            return ;
        par[x]=y;
    }
    bool check(int t)
    {
        for(int i=0;i<=n*m+1;i++)
            par[i]=i;
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(maze[i][j]=='1')
                    vis[i][j]=true;
                else
                    vis[i][j]=false;
        for(int i=1;i<=t;i++)
            vis[p[i].x][p[i].y]=true;
        for(int i=1;i<=n;i++)//最上方编号为0,1-n行编号为1-n*m,最后一行(n+1)编号为n*m+1
            for(int j=1;j<=m;j++)
            {
                if(vis[i][j])
                    continue;
                for(int k=0;k<4;k++)
                {
                    int nx=i+dx[k],ny=j+dy[k];
                    if(ny<1||ny>m)
                        continue;
                    if(nx==0)
                        unite((i-1)*m+j,0);
                    else if(nx==n+1)
                        unite((i-1)*m+j,n*m+1);
                    else if(!vis[nx][ny])
                            unite((i-1)*m+j,(nx-1)*m+ny);
                }
            }
        if(find(0)==find(n*m+1))
            return true;
        return false;
    }
    void solve()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%s",maze[i]+1);
        scanf("%d",&q);
        for(int i=1;i<=q;i++)
        {
            scanf("%d%d",&p[i].x,&p[i].y);
            p[i].x++,p[i].y++;
        }
        if(check(q))//不存在解
        {
            cout<<"-1"<<endl;
            return ;
        }
        int l=1,r=q,ans=0;
        while(l<=r)//二分
        {
            int mid=(l+r)/2;
            if(!check(mid))
            {
                r=mid-1;
                ans=mid;
            }
            else
                l=mid+1;
        }
        cout<<ans<<endl;
    }
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            memset(vis,false,sizeof(vis));
            solve();
        }
        return 0;
    }

     2.BFS

    #include<iostream>
    #include<cstdio>
    #include<queue>
    #include<cstring>
    using namespace std;
    const int maxn=505;
    char maze[maxn][maxn];
    bool vis[maxn][maxn];
    int n,m,q;
    int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
    struct node
    {
        int x,y;
    }p[maxn*maxn];
    bool bfs()
    {
        queue<node> que;
        node cur;
        for(int i=1;i<=n;i++)
        {
            cur.x=0;
            cur.y=i;
            que.push(cur);
        }
        while(que.size())
        {
            cur=que.front();
            que.pop();
            if(cur.x==n+1)
                return true;
            for(int i=0;i<4;i++)
            {
                node next=cur;
                next.x+=dx[i],next.y+=dy[i];
                if(0<=next.x&&next.x<=n+1&&1<=next.y&&next.y<=m&&!vis[next.x][next.y])
                {
                    vis[next.x][next.y]=true;
                    que.push(next);
                }
            }
        }
        return false;
    }
    bool check(int t)
    {
        for(int i=1;i<=n;i++)
            for(int j=1;j<=m;j++)
                if(maze[i][j]=='1')
                    vis[i][j]=true;
                else
                    vis[i][j]=false;
        for(int i=1;i<=t;i++)
            vis[p[i].x][p[i].y]=true;
        return bfs();
    }
    
    void solve()
    {
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;i++)
            scanf("%s",maze[i]+1);
        scanf("%d",&q);
        for(int i=1;i<=q;i++)
        {
            scanf("%d%d",&p[i].x,&p[i].y);
            p[i].x++,p[i].y++;
        }
        if(check(q))
        {
            cout<<"-1"<<endl;
            return ;
        }
        int l=1,r=q,ans=0;
        while(l<=r)
        {
            int mid=(l+r)/2;
            if(!check(mid))
            {
                r=mid-1;
                ans=mid;
            }
            else
                l=mid+1;
        }
        cout<<ans<<endl;
    }
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            memset(vis,false,sizeof(vis));
            solve();
        }
        return 0;
    }

      

  • 相关阅读:
    HDU 1022 Train Problem I
    HDU 1702 ACboy needs your help again!
    HDU 1294 Rooted Trees Problem
    HDU 1027 Ignatius and the Princess II
    HDU 3398 String
    HDU 1709 The Balance
    HDU 2152 Fruit
    HDU 1398 Square Coins
    HDU 3571 N-dimensional Sphere
    HDU 2451 Simple Addition Expression
  • 原文地址:https://www.cnblogs.com/orion7/p/7344485.html
Copyright © 2020-2023  润新知