結果
| 問題 |
No.918 LISGRID
|
| ユーザー |
|
| 提出日時 | 2019-10-21 02:52:10 |
| 言語 | C++14 (gcc 13.3.0 + boost 1.87.0) |
| 結果 |
AC
|
| 実行時間 | 53 ms / 2,000 ms |
| コード長 | 1,693 bytes |
| コンパイル時間 | 2,047 ms |
| コンパイル使用メモリ | 181,652 KB |
| 実行使用メモリ | 13,440 KB |
| 最終ジャッジ日時 | 2024-07-02 17:38:55 |
| 合計ジャッジ時間 | 5,834 ms |
|
ジャッジサーバーID (参考情報) |
judge5 / judge3 |
(要ログイン)
| ファイルパターン | 結果 |
|---|---|
| sample | AC * 3 |
| other | AC * 36 |
ソースコード
#include <bits/stdc++.h>
using namespace std;
int main() {
//入力
int H,W; cin >> H >> W;
vector<int> A,B;
for(int i = 0; i < H; ++i){
int tmp; cin >> tmp;
A.push_back(tmp);
}
for(int j = 0; j < W; ++j){
int tmp; cin >> tmp;
B.push_back(tmp);
}
//sort O(HlogH + WlogW)
sort(A.begin(),A.end());
sort(B.begin(),B.end());
//(i,j)からa[i],b[j]に対応した辺を張る
vector<vector<int>> edge(H*W);//辺
vector<vector<int>> cnt(H,vector<int>(W,0));//入次数
for(int i = 0; i < H; ++i){
for(int j = 0; j < W - A[i]; ++j){
edge[i*W+j].push_back(i*W+j+1);
cnt[i][j+1]++;
}
for(int j = W - A[i]; j + 1 < W; ++j){
edge[i*W+j+1].push_back(i*W+j);
cnt[i][j]++;
}
}
for(int j = 0; j < W; ++j){
for(int i = 0; i < H - B[j]; ++i){
edge[i*W+j].push_back((i+1)*W+j);
cnt[i+1][j]++;
}
for(int i = H - B[j]; i + 1 < H; ++i){
edge[(i+1)*W+j].push_back(i*W+j);
cnt[i][j]++;
}
}
//出力する行列
vector<vector<int>> ans(H,vector<int>(W,0));
//4つ角からスタート
vector<int> sy = {0,0,H-1,H-1},sx = {0,W-1,0,W-1};
//デクリメントしていく値
int val = H*W;
//トポロジカル順を守りながらbfs;
for(int i = 0; i < 4; ++i){
queue<pair<int,int>> pq;
if(!cnt[sy[i]][sx[i]] && !ans[sy[i]][sx[i]]) pq.push({sy[i],sx[i]});
while(pq.size()){
int y = pq.front().first;
int x = pq.front().second;
pq.pop();
ans[y][x] = val--;
for(auto j: edge[y*W+x]){
int s = j/W, t = j%W;
cnt[s][t]--;
if(!cnt[s][t] && !ans[s][t]) pq.push({s,t});
}
}
}
for(int i = 0; i < H; ++i){
for(int j = 0; j < W; ++j){
cout << ans[i][j] << " ";
}
cout << endl;
}
return 0;
}