Problem 1295 : Cubist Artwork
Problem A: Cubist Artwork
http://rose.u-aizu.ac.jp/onlinejudge/ProblemSet/description.jsp?id=1295
- 問題概要
立方体を積み木みたいに組み合わせて形をつくる。
目標の形の2方向からのシルエットがあたえられる。
そのシルエットを満たす最小の立方体の組み合わせの数を答えよ。
- 解法
縦と横に2方向のグリッドに高さを記憶する。
0で初期化
正面から見た場合を縦、横から満た場合を横にする。
2方向のグリッドを左上からそれぞれみて、縦、横の高さが等しい場合はその座標の高さを確定する。
そして、縦横のその高さを使用済みとする。
その作業がおわったらもう一度左上からみていく。
もうすでに高さが確定している場合は飛ばす。
縦の高さ横の高さ両方使用済みの場合飛ばす。
片方だけ使用済みの場合、もう片方をいれる。
両方未使用の場合小さい方をいれる。
いれたものは 使用済みとする。
で、いけたけど、これは想定解法なのだろうか??
- ソース
#include<iostream> #include<string> #include<algorithm> #include<vector> #include<map> #include<set> #include<cstdlib> #include<cstdio> #include<cmath> #include<sstream> #include<cassert> #include<queue> #include<stack> #define REP(i,b,n) for(int i=b;i<n;i++) #define rep(i,n) REP(i,0,n) #define ALL(C) (C).begin(),(C).end() #define pb push_back #define mp make_pair #define vint vector<int> #define FOR(it,o) for(__typeof((o).begin()) it=(o).begin(); it!=(o).end(); ++it) #define lli long long int #define ld long double using namespace std; main(){ int w, d; while(cin >>w >> d){ if( w + d == 0)break; bool uw[w], ud[d]; int hw[w], hd[d], h[w][d]; rep(i, w)uw[i] = false; rep(i, d)ud[i] = false; rep(i, w)rep(j, d)h[i][j] = 0; rep(i, w)cin >> hw[i]; rep(i, d)cin >> hd[i]; rep(k, 2)rep(i, w)rep(j, d){ if(hw[i] == hd[j] && !uw[i] && !ud[j]){ h[i][j] = hw[i]; uw[i] = ud[j] = true; } } rep(i, w)rep(j, d){ if(h[i][j] != 0)continue; if(uw[i] && ud[j])continue; if(uw[i]){ h[i][j] = hd[j]; ud[j] = true; } else if(ud[j]){ h[i][j] = hw[i]; uw[i] = true; } else { h[i][j] = min(hw[i], hd[j]); if(hw[i] < hd[j])uw[i] = true; else ud[j] = true; } } int sum = 0; rep(i, w)rep(j, d)sum += h[i][j]; cout << sum <<endl; } }