解法
DFSにパターン数を足したような再帰すると良い。
枝狩りは、『面積 % 高さ != 0』のときと『すでに誰かの土地がある』とこらへん。
なんかうまく全探できなかったので修行が必要かも。あんまり変数をグローバル化しすぎると良くないね(確信)
計算量が怪しかったが普通に良かった。
ソース
#include<iostream> #include<vector> #include<algorithm> #include<map> #include<cstring> using namespace std; #define fr first #define sc second typedef pair < int , int > Pi; typedef pair < int , Pi > Pii; int h, w, n, ans[10][10]; vector< Pii > memo; int wy, wx; void plus_n( int y, int x, int nt){ wy = y; wx = ( x + nt ) % w; if(!wx) wy++; return ; } int dfs( const int mas[][10], const int used, const int y, const int x){ if( y == h){ //exit memcpy( ans, mas, sizeof(int)*100); return 1; } int ret = 0; if( mas[y][x] != 0){ plus_n( y, x, 1); ret += dfs( mas, used, wy, wx); }else{ for(int bit = 0 ; bit < n ; bit++ ){ if( (used >> bit) & 1 ) continue; // もうやってある for(int i = 1 ; i <= memo[bit].fr ; i++ ){ //高さ決定 if( memo[bit].fr % i != 0 ) continue; // 長方形無理 int height = i, width = memo[bit].fr / i; if( y <= memo[bit].sc.fr && y > memo[bit].sc.fr - height && x <= memo[bit].sc.sc && x > memo[bit].sc.sc - width && y + height - 1 < h && x + width - 1 < w){ int java[10][10]; bool ok = true; memcpy( java, mas, sizeof(int)*100); for(int j = 0 ; j < height ; j++ ){ for(int k = 0 ; k < width ; k++ ){ if(java[j + y][k + x]) ok = false; java[j + y][k + x] = bit + 1; } } if(ok){ plus_n( y, x, width); ret += dfs( java, used|(1<<bit), wy, wx); } } } } } return ret; } int main(){ while(cin >> w >> h >> n , w){ memo.resize( n); for(int i = 0, bf ; i < n ; i++ ){ cin >> bf; cin >> memo[bf - 1].fr; } for(int i = 0, c ; i < h ; i++ ){ for(int j = 0 ; j < w ; j++ ){ cin >> c; if(c)memo[c - 1].sc = Pi( i, j); } } int mas[10][10] = {{}}; if(dfs( mas, 0, 0, 0) == 1){ for(int i = 0 ; i < h ; i++ ){ for(int j = 0 ; j < w ; j++ ){ cout << ( j ? " " : "" ) << ans[i][j]; } cout << endl; } }else cout << "NA" << endl; } }
0 件のコメント:
コメントを投稿