码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-09-28 14:36:17      阅读:275      评论:0      收藏:0      [点我收藏+]

标签:using   排序   detail   stdout   http   mat   set   carp   ||   

题意:

构造一个矩阵,使得:

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

构造的矩阵除了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)

标签:using   排序   detail   stdout   http   mat   set   carp   ||   

原文地址:https://www.cnblogs.com/myx12345/p/9718159.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!