題目鏈結
1448 二染色問題
topcoder
基準時間限制:1 秒 空間限制:131072 kb 分值: 40
難度:4級演算法題
乙個n*n的網格,初始為白色。現在有乙個k*k的印章,每次操作:你可以用印章把網格中乙個k*k的子矩形染成黑色或白色。如果乙個格仔被多次染色,那麼後一次染色會覆蓋掉前一次的。現在,給你n*n的由黑白兩色構成的圖案board(board[i][j]為第i行第j列格仔的顏色,不是白字母『w』表示,就是黑由字母『b』表示),問是否能通過若干次操作,將網格從初始狀態染成圖案board的樣子。如果可以輸出"possible",否則輸出"impossible".
input
多組測試資料,第一行乙個整數t,表示測試資料數量,1<=t<=5output每組測試資料有相同的結構構成:
每組資料一行兩個整數n與k,其中1<=k<=n<=20。
之後n行,每行n個字元,表示board,字元都由『w』與『b』構成。
每組資料一行輸出,即是否可能染出board圖案來。input示例
3output示例4 3bbbw
bwww
bwww
wwww
2 2bw
wb6 2
bwbwbb
wbwbbb
bwbwbb
wbwbbb
bbbbbb
bbbbbb
possible官方題解:impossible
possible
可以嘗試逆向思維,最後一塊無論是黑是白,都一定是k*k的連通塊。倒數第i塊,其一部分被最後的i-1塊遮擋,其餘部分必然同色且分布在k*k的矩形內。因此可以逆向貪心構造,直到每乙個小正方形被覆蓋為止。
其實這個題就像以前做過的乙個貼海報的題目,首先確定乙個全部為同色的k*k的塊,然後將這些塊內的格仔標記為訪問過了,對於後面的k*k的塊,這時候只需要判斷除了已經訪問的點外,其他的是否為同色,知道找不到這樣的塊為止,到最後再掃一遍,若存在沒被訪問的且為black的就說明不存在解決方案。
#include#include#include#include#include#include#includeusing namespace std;
#define rep(i,a,n) for (int i=a;i=a;i--)
#define pb push_back
#define fi first
#define se second
typedef vectorvi;
typedef long long ll;
typedef pairpii;
const ll mod=1000000007;
const int maxn=20+10;
char s[maxn][maxn];
bool vis[maxn][maxn];
int main()
{ int cas;
scanf("%d",&cas);
while(cas--)
{memset(vis,false,sizeof(vis));
int n,k;
scanf("%d%d",&n,&k);
bool flag=true;
for(int i=1;i<=n;i++) scanf("%s",s[i]+1);
while(flag)
{flag=false;
for(int i=1;i<=n-k+1;i++)
{for(int j=1;j<=n-k+1;j++)
{int sum1=0,sum2=0;
bool f=false;
for(int ii=i;ii
51nod 1448 二染色問題
題意 乙個n n的網格,初始為白色。現在有乙個k k的印章,每次操作 你可以用印章把網格中乙個k k的子矩形染成黑色或白色。如果乙個格仔被多次染色,那麼後一次染色會覆蓋掉前一次的。現在,給你n n的由黑白兩色構成的圖案board board i j 為第i行第j列格仔的顏色,不是白字母 w 表示,就...
51NOD 活動安排問題之二
有若干個活動,第i個開始時間和結束時間是 si,fi 活動之間不能交疊,要把活動都安排完,至少需要幾個教室?輸入 第一行乙個正整數n n 10000 代表活動的個數。第二行到第 n 1 行包含n個開始時間和結束時間。開始時間嚴格小於結束時間,並且時間都是非負整數,小於1000000000 輸出 一行...
51nod 貪心入門之二 活動安排問題
有若干個活動,第i個開始時間和結束時間是 si,fi 只有乙個教室,活動之間不能交疊,求最多安排多少個活動?分析 我們就是想提高教室地利用率,盡可能多地安排活動。考慮容易想到的幾種貪心策略 1 開始最早的活動優先,目標是想盡早結束活動,讓出教室。然而,這個顯然不行,因為最早的活動可能很長,影響我們進...