SRM505 Div1 Easy(300), Div2 Hard(900) RectangleArea
Div2だと900。このパターンは初めて見た。
R0を決めると全てのRi,Cjが定まるとき、RiはR0に比例しCjはR0に反比例するので打ち消し合って面積が求められる。
どれか1つを決めると他が定まるRi,Cjを1つの組として、グループ分けする。あるRiとCjが同じ組になるのはAijが既知である場合。組の個数をcとすると、任意の組2つは適切な問い1回で同じ組にできるし、1回の問いで3つ以上の組を纏めることはできないので、c-1が答。
#include <vector> #include <string> using namespace std; // Union-Find木 class UnionFind { vector<int>p,r; public: UnionFind(int n):p(n,-1),r(n){} int find(int x){return p[x]>=0?p[x]=find(p[x]):x;} void unite(int x,int y){x=find(x),y=find(y); if(x!=y)if(r[x]<r[y])p[x]=y;else p[y]=x,r[x]+=r[x]==r[y];} bool same(int x, int y){return find(x)==find(y);} bool root(int x){return x==find(x);} }; class RectangleArea{public: int minimumQueries( vector <string> known ) { int N = (int)known[0].size(); int M = (int)known.size(); UnionFind u(N+M); for ( int i=0; i<N; i++ ) for ( int j=0; j<M; j++ ) if ( known[j][i]=='Y' ) u.unite(i,N+j); int c = 0; for ( int i=0; i<N+M; i++ ) if ( u.root(i) ) c++; return c-1; }};