Problem Description
Little Bob found an interesting mobile game called KAMI in Google Play recently. In this game, you are given a 16*10 grid, and each cell is one of the 4 different colors.
The only thing you can do in this game is to choose a cell and a color, and then the entire 4-connected component, which contains the cell and has the same color as the cell, will be painted with the chosen color.
Your goal is to make all cells painted with the same color with the least painting steps. Also note that the optimal painting steps will be given, just the same as the original game.
For your convenience, we label the colors with integers 1…4. In the grid, we index the rows with integers 1…16 from top to bottom, and index the columns with integers 1…10 from left to right. Thus the cell in the i-th row and j-th column will be denoted by (i, j).
Once you choose to paint cell (7, 1) with orange color in the above picture, we will obtain:
Input
The first line contains an integer T (T<=5), which means there are T test cases in the input.
For each test case, the first line contains a positive integer n (n<=8), which denotes the optimal painting steps of this case. We ensure this is the least painting times to achieve the goal.
The next 16 lines in each test case describe the initial colors of each cell in the grid. Each line contains a string of length 10, which consists of digits ‘1’~‘4’. For each test case, we ensure that the 4 colors all appear in the initial state.
Output
For each test case, output “Case #x:” (x means the case ID) in a separate line first. Then you should output exactly n lines. Each line contains three integers c, x, y (1<=c<=4, 1<=x<=16, 1<=y<=10), which means you choose to paint cell (x, y) with color c in this step.
If there exists more than one optimal solutions, you can output an arbitrary one.
Sample Input
2
3
4444444444
3332222333
3111111113
3332222313
3111111113
3132222333
3111111113
3332222313
3111111113
3132222333
3111111113
3332222313
3111111113
3132222333
3332222333
4444444444
5
1111213131
1111213131
4444243444
1111213131
4444444434
1111213131
2222222232
1111213131
1111213131
1111213131
1111213131
1111213131
1111213131
1111213131
1111213131
1111213131
Sample Output
Case #1:
2 14 2
3 15 7
4 12 8
Case #2:
4 4 5
4 16 9
2 5 10
1 7 10
3 16 10
Source
2014 ACM/ICPC Asia Regional Anshan Online
题意:
给定若干步骤,使得最后的图是同一种颜色;
每次染色只能染周围相邻的同样颜色的方块;
这种问题当然是搜索解决的;
(据说当时网络赛没有AC的,
不知道是不是真的,orz;
代码量还好,调试的时候得耐心;
其实主要思路的难点就在于:
每次我们只需选一个点进行染色即可;
而不是遍历整个图表;
然后选4种颜色尝试染色;
很不错的一道dfs+bfs题;
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 200005
#define inf 0x3f3f3f3f
#define INF 0x7fffffff
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const int mod = 1e9 + 7;
#define Mod 20100403
#define sq(x) (x)*(x)
#define eps 1e-10
const int N = 1505;
inline int rd() {
int x = 0;
char c = getchar();
bool f = false;
while (!isdigit(c)) {
if (c == '-') f = true;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f ? -x : x;
}
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }
const int r = 16;
const int c = 10;
char grap[r + 1][c + 1];
int ans[r*c+2];
int dr[] = { 0,1,0,-1 };
int dc[] = { 1,0,-1,0 };
int n;
bool OK;
struct node {
int r, c;
node(){}
node(int r, int c):r(r),c(c){}
};
bool check() {
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
if (grap[i][j] != grap[1][1])return false;
}
}
return true;
}
void dfs(int x, int y, int cur) {
char tmp[r + 1][c + 1];
int vis[r + 1][c + 1];
if (cur == n) {
if (check())OK = true;
return;
}
int curColor = grap[x][y] - '0';
for (int i = 1; i <= 4; i++) {
if (i == curColor)continue;
memcpy(tmp, grap, sizeof(grap));
ms(vis); queue<node>q;
q.push(node(x, y));
vis[x][y] = true;
while (!q.empty()) {
node front = q.front(); q.pop();
grap[front.r][front.c] = i + '0';
for (int j = 0; j < 4; j++) {
int r = front.r + dr[j];
int c = front.c + dc[j];
if (grap[r][c] - '0' != curColor || vis[r][c])continue;
vis[r][c] = true; q.push(node(r, c));
}
}
ans[cur] = i; dfs(x, y, cur + 1);
if (OK)return;
memcpy(grap, tmp, sizeof(tmp));
}
}
void sol() {
rdint(n);
for (int i = 1; i <= r; i++)scanf("%s", grap[i] + 1);
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
if (grap[i - 1][j] == grap[i][j] || grap[i][j - 1] == grap[i][j])continue;
OK = false;
dfs(i, j, 0);
if (OK) {
for (int k = 0; k < n; k++) {
cout << ans[k] << ' ' << i << ' ' << j << endl;
}
}
}
}
}
int main()
{
//ios::sync_with_stdio(false);
int T; rdint(T);
int cnt = 1;
while (T--) {
printf("Case #%d:\n", cnt++);
sol();
}
return 0;
}
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<set>
#include<vector>
#include<queue>
#include<bitset>
#include<ctime>
#include<deque>
#include<stack>
#include<functional>
#include<sstream>
#include<cctype>
//#pragma GCC optimize("O3")
using namespace std;
#define maxn 200005
#define inf 0x3f3f3f3f
#define INF 0x7fffffff
#define rdint(x) scanf("%d",&x)
#define rdllt(x) scanf("%lld",&x)
typedef long long ll;
typedef unsigned long long ull;
typedef unsigned int U;
#define ms(x) memset((x),0,sizeof(x))
const int mod = 1e9 + 7;
#define Mod 20100403
#define sq(x) (x)*(x)
#define eps 1e-10
const int N = 1505;
inline int rd() {
int x = 0;
char c = getchar();
bool f = false;
while (!isdigit(c)) {
if (c == '-') f = true;
c = getchar();
}
while (isdigit(c)) {
x = (x << 1) + (x << 3) + (c ^ 48);
c = getchar();
}
return f ? -x : x;
}
ll gcd(ll a, ll b) {
return b == 0 ? a : gcd(b, a%b);
}
ll sqr(ll x) { return x * x; }
const int r = 16;
const int c = 10;
char grap[r + 1][c + 1];
int ans[r*c+2];
int dr[] = { 0,1,0,-1 };
int dc[] = { 1,0,-1,0 };
int n;
bool OK;
struct node {
int r, c;
node(){}
node(int r, int c):r(r),c(c){}
};
bool check() {
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
if (grap[i][j] != grap[1][1])return false;
}
}
return true;
}
void dfs(int x, int y, int cur) {
char tmp[r + 1][c + 1];
int vis[r + 1][c + 1];
if (cur == n) {
if (check())OK = true;
return;
}
int curColor = grap[x][y] - '0';
for (int i = 1; i <= 4; i++) {
if (i == curColor)continue;
memcpy(tmp, grap, sizeof(grap));
ms(vis); queue<node>q;
q.push(node(x, y));
vis[x][y] = true;
while (!q.empty()) {
node front = q.front(); q.pop();
grap[front.r][front.c] = i + '0';
for (int j = 0; j < 4; j++) {
int r = front.r + dr[j];
int c = front.c + dc[j];
if (grap[r][c] - '0' != curColor || vis[r][c])continue;
vis[r][c] = true; q.push(node(r, c));
}
}
ans[cur] = i; dfs(x, y, cur + 1);
if (OK)return;
memcpy(grap, tmp, sizeof(tmp));
}
}
void sol() {
rdint(n);
for (int i = 1; i <= r; i++)scanf("%s", grap[i] + 1);
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
if (grap[i - 1][j] == grap[i][j] || grap[i][j - 1] == grap[i][j])continue;
OK = false;
dfs(i, j, 0);
if (OK) {
for (int k = 0; k < n; k++) {
cout << ans[k] << ' ' << i << ' ' << j << endl;
}
}
}
}
}
int main()
{
//ios::sync_with_stdio(false);
int T; rdint(T);
int cnt = 1;
while (T--) {
printf("Case #%d:\n", cnt++);
sol();
}
return 0;
}