1. 程式人生 > >【CF659F】Polycarp and Hay(並查集,bfs)

【CF659F】Polycarp and Hay(並查集,bfs)

jar 上下 等於 b+ ios str %d class style

題意:

構造一個矩陣,使得:

矩陣所有格子中數字都小於等於原矩陣,並且至少有一個元素和原矩陣相等,

構造的矩陣除了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("\n"); 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\n",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\n"); 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

【CF659F】Polycarp and Hay(並查集,bfs)