BOJ 17136-カラーペーパーの貼り付け
タイムアウトメモリ制限正解の送信正解正解正解正解率1秒512 MB 12934758235732.164%
図1に示すように、正方形の色紙が5種類あります.色紙の大きさは1×1, 2×2, 3×3, 4×4, 5×5は全部で5種類あり、カラーペーパーはそれぞれ5種類あります.
色のサイズは10×10人分の紙に貼る.紙は1×1つの大きさの格子に分けられ、各格子には0または1と書かれています.1と書いてある格子はすべて色紙で覆わなければなりません.色紙を貼るときは、紙の限界を超えたり、重ねたりしてはいけません.また、セルの境界と一致するようにします.0と書いた格子に色紙はありません.
用紙を与えた場合、1のマスをすべて貼るのに必要な最小色紙個数を求める.
全部で10行あり、1ページあたりの数字です.
1をすべて上書きするために必要な最小色紙数を出力します.1をすべて上書きできない場合は、-1を出力します.
近づくのは難しくない.すべての格子に色紙を貼ればいいです.
希望のない部分は後追跡で返し、Brook Forceで入手すればよい.
解法によっては、コードの長さが千差万別になる可能性があります.
最初はベクトルが関数パラメータだと思っていましたが、
そうする必要はないようだ.
残りをパラメータとして脱出ゲートに適用する.
y,x値の前処理も簡単でよい.
大きさ1~5を確認し、色紙があれば貼り付けます.
復帰する前に、値を変えて、出るときに値を変える仕事をすればいいです.
質問する
図1に示すように、正方形の色紙が5種類あります.色紙の大きさは1×1, 2×2, 3×3, 4×4, 5×5は全部で5種類あり、カラーペーパーはそれぞれ5種類あります.
色のサイズは10×10人分の紙に貼る.紙は1×1つの大きさの格子に分けられ、各格子には0または1と書かれています.1と書いてある格子はすべて色紙で覆わなければなりません.色紙を貼るときは、紙の限界を超えたり、重ねたりしてはいけません.また、セルの境界と一致するようにします.0と書いた格子に色紙はありません.
用紙を与えた場合、1のマスをすべて貼るのに必要な最小色紙個数を求める.
入力
全部で10行あり、1ページあたりの数字です.
しゅつりょく
1をすべて上書きするために必要な最小色紙数を出力します.1をすべて上書きできない場合は、-1を出力します.
に近づく
近づくのは難しくない.すべての格子に色紙を貼ればいいです.
希望のない部分は後追跡で返し、Brook Forceで入手すればよい.
解法によっては、コードの長さが千差万別になる可能性があります.
に答える
最初はベクトル
そうする必要はないようだ.
残りをパラメータとして脱出ゲートに適用する.
y,x値の前処理も簡単でよい.
大きさ1~5を確認し、色紙があれば貼り付けます.
復帰する前に、値を変えて、出るときに値を変える仕事をすればいいです.
#include <bits/stdc++.h>
using namespace std;
#define ll long long int
#define FUP(i, a, b) for(int i = a; i <= b; i++)
#define FDOWN(i, a, b) for(int i = a; i >= b; i--)
#define MS(a, b) memset(a, b, sizeof(a))
#define ALL(v) v.begin(), v.end()
#define CIN(a) cin >> a;
#define CIN2(a, b) cin >> a >> b
#define CIN3(a, b, c) cin >> a >> b >> c
#define COUT(a) cout << a
#define COUT2(a, b) cout << a << ' ' << b
#define COUT3(a, b, c) cout << a << ' ' << b << ' ' << c
#define ENDL cout << '\n'
int dy[4] = { -1, 1, 0, 0 };
int dx[4] = { 0, 0, 1, -1 };
int answer = 30, paper[5] = { 5, 5, 5, 5, 5 };
vector<vector<int>> arr(10);
int use_paper()
{
int ret = 25;
FUP(i, 0, 4) ret -= paper[i];
return ret;
}
void change(int y, int x, int len)
{
FUP(i, y, y + len)
{
FUP(j, x, x + len)
{
arr[i][j] ^= 1;
}
}
}
void solve(int y, int x, int remain)
{
if (remain == 0)
{
answer = min(answer, use_paper());
return;
}
if (x >= 10)
{
solve(y + 1, 0, remain);
return;
}
if (!arr[y][x]) solve(y, x + 1, remain);
FUP(len, 0, 4)
{
if (x + len >= 10 || y + len >= 10) break;
bool ok = true;
FUP(i, y, y + len)
{
if (!arr[i][x + len]) ok = false;
}
FUP(j, x, x + len)
{
if (!arr[y + len][j]) ok = false;
}
if (!ok) break;
if (!paper[len]) continue;
change(y, x, len);
paper[len]--;
solve(y, x + len + 1, remain - (len + 1) * (len + 1));
paper[len]++;
change(y, x, len);
}
}
int main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int remain = 0;
FUP(i, 0, 9)
{
arr[i].resize(10);
FUP(j, 0, 9)
{
CIN(arr[i][j]);
remain += arr[i][j];
}
}
solve(0, 0, remain);
answer == 30 ? COUT(-1) : COUT(answer);
return 0;
}
Reference
この問題について(BOJ 17136-カラーペーパーの貼り付け), 我々は、より多くの情報をここで見つけました https://velog.io/@gyuho/BOJ-17136-색종이-붙이기テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol