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;
  }
}