UVA 1665 Islands
Posted cynchanpin
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVA 1665 Islands相关的知识,希望对你有一定的参考价值。
题意:输入一个n*m矩阵,每一个格子都有一个正整数,再输入T个整数ti,对于每一个ti,输出大于ti的正整数组成多少个四连快
思路:正着做的话事实上相当于删除连通块,而假设反着做的话就相当于变成添加连通块,把格子都编号然后排序。用并查集
#include<bits/stdc++.h> using namespace std; const int maxn = 1005; const int maxq = 1e5+1; int pre[maxn*maxn]; int Find(int x) { return x==pre[x]?x:pre[x]=Find(pre[x]); } struct Node { int x,y; int val; }nodes[1005*1005]; int mapp[maxn][maxn]; int qq[maxq]; int n,m; int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; bool cmp(Node a,Node b) { return a.val<b.val; } int main() { int T; scanf("%d",&T); while (T--) { scanf("%d%d",&n,&m); for (int i = 0;i<n;i++) for (int j = 0;j<m;j++) { scanf("%d",&mapp[i][j]); int pos = i*m+j; nodes[pos].x=i; nodes[pos].y=j; nodes[pos].val=mapp[i][j]; } int ans = 0; int q; scanf("%d",&q); for (int i = 0;i<q;i++) scanf("%d",&qq[i]); memset(pre,-1,sizeof(pre)); sort(nodes,nodes+n*m,cmp); int k = n*m-1; for (int i = q-1;i>=0;i--) { if (qq[i]< nodes[k].val) { while (k>=0 && qq[i]<nodes[k].val) { int pos = nodes[k].x*m+nodes[k].y; if (!~pre[pos]) pre[pos]=pos,ans++; for (int di=0;di<4;di++) { int dx = nodes[k].x+dir[di][0]; int dy = nodes[k].y+dir[di][1]; if (dx>=0 && dx<n&&dy>=0&&dy<m&&mapp[dx][dy]>qq[i]) { int ppos = dx*m+dy; if (~pre[ppos]) { int u = Find(ppos); int v = Find(pos); if (u!=v) pre[u]=v,ans--; } } } k--; } if (k<0) { for (;i>=0;i--) { qq[i]=ans; } break; } } qq[i]=ans; } for (int i = 0;i<q;i++) printf("%d ",qq[i]); printf("\n"); } }
以上是关于UVA 1665 Islands的主要内容,如果未能解决你的问题,请参考以下文章
BZOJ1665 Usaco2006 Open The Climbing Wall
[LintCode] Number of Islands(岛屿个数)
leetcode200. Number of Islands