zoukankan      html  css  js  c++  java
  • CodeForces 659F Polycarp and Hay

    并查集,$dfs$。

    从大的数字往里加,每加一个数字合并一下连通块,判断连通块内数字个数是否够,以及k能不能被当前加入的数字整除。然后$dfs$一下构造答案。

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<vector>
    #include<map>
    #include<set>
    #include<queue>
    #include<stack>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const double pi=acos(-1.0),eps=1e-6;
    void File()
    {
        freopen("D:\in.txt","r",stdin);
        freopen("D:\out.txt","w",stdout);
    }
    template <class T>
    inline void read(T &x)
    {
        char c=getchar(); x=0;
        while(!isdigit(c)) c=getchar();
        while(isdigit(c)) {x=x*10+c-'0'; c=getchar();}
    }
    
    const int maxn=1010;
    int n,m,sz,c; LL k;
    struct X { int r,c; LL v; }s[maxn*maxn];
    int fa[maxn*maxn],a[maxn][maxn],cnt[maxn*maxn]; LL ans[maxn][maxn];
    bool f[maxn][maxn],q;
    int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
    
    int Find(int x)
    {
        if(x!=fa[x]) fa[x]=Find(fa[x]);
        return fa[x];
    }
    
    bool cmp(X a,X b) { return a.v<b.v; }
    
    void work(int a,int b)
    {
        if(b<0||b>=n*m) return;
    
        int fx=Find(a),fy=Find(b);
    
        if(f[b/m][b%m]==0) return;
    
        if(fx==fy) return;
        fa[fy]=fx;
        cnt[fx]=cnt[fx]+cnt[fy]; cnt[fy]=0;
    }
    
    bool check(int a,int b)
    {
        if(a>=0&&a<n&&b>=0&&b<m) return 1;
        return 0;
    }
    
    void dfs(int x,int y,LL v,int f)
    {
        c++; ans[x][y]=v; if(c>=f) return;
        for(int i=0;i<4;i++)
        {
            int tx=x+dir[i][0],ty=y+dir[i][1];
            if(!check(tx,ty)) continue;
            if(a[tx][ty]<v) continue;
            if(ans[tx][ty]!=0) continue;
            dfs(tx,ty,v,f); if(c>=f) return;
        }
    }
    
    int main()
    {
        scanf("%d%d%lld",&n,&m,&k);
        for(int i=0;i<n*m;i++) fa[i]=i,cnt[i]=1;
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                scanf("%lld",&a[i][j]);
                s[sz].r=i; s[sz].c=j; s[sz].v=a[i][j]; sz++;
            }
        }
        sort(s,s+sz,cmp);
    
        for(int j=sz-1; j>=0; j--)
        {
            int id1=s[j].r*m+s[j].c,id2;
            if(check(s[j].r-1,s[j].c))
            {
                id2=(s[j].r-1)*m+s[j].c;
                work(id1,id2);
            }
            if(check(s[j].r+1,s[j].c))
            {
                id2=(s[j].r+1)*m+s[j].c;
                work(id1,id2);
            }
            if(check(s[j].r,s[j].c-1))
            {
                id2=s[j].r*m+s[j].c-1;
                work(id1,id2);
            }
            if(check(s[j].r,s[j].c+1))
            {
                id2=s[j].r*m+s[j].c+1;
                work(id1,id2);
            }
            f[s[j].r][s[j].c]=1;
    
    
            int d=Find(id1);
            if(k%s[j].v==0&&(LL)cnt[d]>=k/s[j].v)
            {
                dfs(s[j].r,s[j].c,s[j].v,(int)(k/s[j].v));
                q=1; break;
            }
            if(q) break;
        }
    
    
        if(!q) { printf("NO
    "); return 0;}
        printf("YES
    ");
        for(int i=0;i<n;i++)
        {
            for(int j=0;j<m;j++)
            {
                printf("%lld",ans[i][j]);
                printf(" ");
            }
           printf("
    ");
        }
        return 0;
    }
  • 相关阅读:
    sqlhelper使用指南
    大三学长带我学习JAVA。作业1. 第1讲.Java.SE入门、JDK的下载与安装、第一个Java程序、Java程序的编译与执行 大三学长带我学习JAVA。作业1.
    pku1201 Intervals
    hdu 1364 king
    pku 3268 Silver Cow Party
    pku 3169 Layout
    hdu 2680 Choose the best route
    hdu 2983
    pku 1716 Integer Intervals
    pku 2387 Til the Cows Come Home
  • 原文地址:https://www.cnblogs.com/zufezzt/p/5884426.html
Copyright © 2011-2022 走看看