zoukankan      html  css  js  c++  java
  • 【CF659F】Polycarp and Hay(并查集,bfs)

    题意:

    构造一个矩阵,使得:

    矩阵所有格子中数字都小于等于原矩阵,并且至少有一个元素和原矩阵相等,

    构造的矩阵除了0以外的数字必须联通并且相等,矩阵中元素之和为K。

    n,m<=1e3,1<=K<=1e18

    思路:

    From https://blog.csdn.net/morejarphone/article/details/51037918

    对每个格子的数字进行排序,那么一个格子的数字最多能够填的格子数就是他上下左右格子能够填的格子

    数的和,这个可以用并查集来维护

    然后枚举每个格子,如果这个格子的数字能够整除k并且这个格子能够填的个数足够,就可以从这个格子出发

    bfs一遍找到需要的格子

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<string>
      4 #include<cmath>
      5 #include<iostream>
      6 #include<algorithm>
      7 #include<map>
      8 #include<set>
      9 #include<queue>
     10 #include<vector>
     11 using namespace std;
     12 typedef long long ll;
     13 typedef unsigned int uint;
     14 typedef unsigned long long ull;
     15 typedef pair<int,int> PII;
     16 typedef vector<int> VI;
     17 #define fi first
     18 #define se second s
     19 #define MP make_pair
     20 #define N   1100
     21 #define M   1100000
     22 #define MOD 1000000007
     23 #define eps 1e-8 
     24 #define pi acos(-1)
     25 #define oo 2e9+1
     26 
     27 int dx[4]={1,-1,0,0},
     28     dy[4]={0,0,-1,1};
     29     
     30 struct node
     31 {
     32     int x,y;
     33     ll z;
     34 }b[M],q[M];
     35 
     36 ll a[N][N],K;
     37 int vis[N][N],num[N][N],f[M],size[M],n,m;
     38     
     39 
     40 int read()
     41 { 
     42    int v=0,f=1;
     43    char c=getchar();
     44    while(c<48||57<c) {if(c=='-') f=-1; c=getchar();}
     45    while(48<=c&&c<=57) v=(v<<3)+v+v+c-48,c=getchar();
     46    return v*f;
     47 }
     48 
     49 
     50 bool cmp(node a,node b)
     51 {
     52     return a.z>b.z;
     53 } 
     54 
     55 int find(int k)
     56 {
     57     if(f[k]!=k) f[k]=find(f[k]);
     58     return f[k];
     59 }
     60 
     61 
     62 void bfs(int x,int y,ll cnt)
     63 {
     64     int t=0;
     65     int w=1;
     66     q[1].x=x; q[1].y=y;
     67     memset(vis,0,sizeof(vis));
     68     vis[x][y]=1;
     69     cnt--;
     70     while(t<=w&&cnt)
     71     {
     72         t++;
     73         int nowx=q[t].x;
     74         int nowy=q[t].y;
     75         vis[nowx][nowy]=1;
     76         for(int i=0;i<4;i++)
     77         {
     78             int tx=nowx+dx[i];
     79             int ty=nowy+dy[i];
     80             if(!tx||tx>n||!ty||ty>m||vis[tx][ty]) continue;
     81             if(a[tx][ty]>=a[x][y])
     82             {
     83                 vis[tx][ty]=1;
     84                 q[++w].x=tx;
     85                 q[w].y=ty;
     86                 cnt--;
     87                 if(cnt<=0) break;
     88             }
     89         }
     90     }
     91     for(int i=1;i<=n;i++)
     92     {
     93         for(int j=1;j<=m;j++)
     94         {
     95             if(vis[i][j]) printf("%lld",a[x][y]);
     96              else printf("0");
     97             if(j<m) printf(" ");
     98         }
     99         printf("
    ");
    100     }
    101 }
    102         
    103         
    104 int main()
    105 {
    106     //freopen("cf659f.in","r",stdin);
    107     //freopen("cf659f.out","w",stdout);
    108     scanf("%d%d%lld",&n,&m,&K);
    109     for(int i=1;i<=n;i++)
    110      for(int j=1;j<=m;j++) scanf("%lld",&a[i][j]); 
    111     int tot=0;
    112     for(int i=1;i<=n;i++)
    113      for(int j=1;j<=m;j++) 
    114      {
    115          num[i][j]=(i-1)*m+j;
    116          size[num[i][j]]=1;
    117          f[num[i][j]]=num[i][j];
    118          b[++tot].x=i;
    119          b[tot].y=j;
    120          b[tot].z=a[i][j];
    121      }
    122     sort(b+1,b+tot+1,cmp);
    123 
    124     memset(vis,0,sizeof(vis));
    125     for(int i=1;i<=tot;i++)
    126     {
    127          vis[b[i].x][b[i].y]=1;
    128          for(int j=0;j<4;j++)
    129          {
    130              int x=b[i].x+dx[j];
    131             int y=b[i].y+dy[j];
    132             if(x&&x<=n&&y&&y<=m&&vis[x][y])
    133             {
    134                 int p=find(num[b[i].x][b[i].y]);
    135                 int q=find(num[x][y]);
    136                 if(p!=q)
    137                 {
    138                     f[q]=p;
    139                     size[p]+=size[q];
    140                 }
    141             }
    142          }
    143     }
    144     
    145 //    for(int i=1;i<=n;i++)
    146 //     for(int j=1;j<=m;j++) printf("%d
    ",size[num[i][j]]);
    147 
    148     int ans=0;
    149     for(int i=1;i<=n;i++)
    150     {
    151         for(int j=1;j<=m;j++)
    152            if(K%a[i][j]==0&&size[num[i][j]]>=K/a[i][j])
    153            {
    154                printf("YES
    ");
    155                bfs(i,j,K/a[i][j]);
    156                ans=1; break;
    157            }
    158         if(ans) break;
    159     }
    160     if(!ans) printf("NO");
    161      
    162 }
    163     
    164     
    165 
    166 
    167             
    168         
  • 相关阅读:
    (转)C#中Thread.sleep()
    ZigBee无线信道组成
    JSP应用html乱码的终极解决办法
    How to size text using ems
    iframe和frame的区别
    [洛谷P2827]蚯蚓
    [洛谷P3391]【模板】文艺平衡树(Splay)
    [洛谷P4180]严格次小生成树
    HTTP 常见鉴权
    使用 rsync 备份/复制 系统
  • 原文地址:https://www.cnblogs.com/myx12345/p/9718159.html
Copyright © 2011-2022 走看看