#include <cstdio>
#include <queue>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
using namespace std;
const int statusNum = 1024*64; //
char initStatus[4][4];
int handleOP[16] = {4383, 8751, 17487, 34959,
4593, 8946, 17652, 35064,
7953, 12066, 20292, 36744,
61713, 61986, 62532, 63624}; // xor
char statusColorMap[statusNum]; // 0: white, 1: grey, 2: black
char statusLevelMap[statusNum];
int statusUpNodeMap[statusNum];
struct move{
int x;
int y;
};
struct move statusMoveMap[statusNum];
// void printStatus(bool status[4][4]) {
// printf("=============================\n");
// for (int i = 0; i <= 3; i++) {
// for(int j = 0; j <=3; j++) {
// printf("%d", status[i][j]);
// }
// printf("\n");
// }
// printf("=============================\n");
// }
// void handleStatus(bool status[4][4], int i, int j) {
// status[i][j] = !status[i][j];
// for (int a = 0; a <= 3; a++) {
// status[a][j] = !status[a][j];
// }
// for (int b = 0; b <= 3; b++) {
// status[i][b] = !status[i][b];
// }
// }
// int getStatusId(bool status[4][4]) {
// int id = 0;
// for(int i = 0; i <= 3; i++) {
// for(int j = 0; j <= 3; j++) {
// id += status[i][j] * pow(2, (j + i*4));
// }
// }
// return id;
// }
int getStatusId(char status[4][4]) {
int id = 0;
for(int i = 0; i <= 3; i++) {
for(int j = 0; j <= 3; j++) {
if (status[i][j] == '+') {
id += pow(2, (j + i*4));
}
}
}
return id;
}
// void getHandleOP() {
// bool status[4][4] = {0};
// for(int i = 0; i <= 3; i++) {
// for (int j = 0; j <= 3; j++) {
// memset((void *)status, 0, sizeof(bool)*16);
// handleStatus(status, i, j);
// // printStatus(status);
// printf("%d\n", getStatusId(status));
// }
// }
// }
bool isOK(int status) {
if (status == 0) {
return true;
}
return false;
}
void printTrace(int finalStatus) {
int nextStatus = finalStatus;
stack<string> traceStack;
while(statusUpNodeMap[nextStatus] != -1) {
char trace[5] = "";
// printf("%d %d\n", statusMoveMap[nextStatus].x, statusMoveMap[nextStatus].y);
sprintf(trace, "%d %d\n", statusMoveMap[nextStatus].y, statusMoveMap[nextStatus].x);
traceStack.push(string(trace));
nextStatus = statusUpNodeMap[nextStatus];
}
while(!traceStack.empty()) {
printf("%s", traceStack.top().c_str());
traceStack.pop();
}
}
void searchMethod(int status) {
statusUpNodeMap[status] = -1;
statusLevelMap[status] = 0;
statusColorMap[status] = 1;
queue<int> statusNeedToSearch;
statusNeedToSearch.push(status);
while(1) {
if (statusNeedToSearch.size() == 0) {
printf("Impossible\n");
return;
}
int statusToHandle = statusNeedToSearch.front();
statusNeedToSearch.pop();
for(int i = 0; i <= 15; i++) {
int statusAfterHandle = statusToHandle^handleOP[i];
if (statusColorMap[statusAfterHandle] == 0) {
statusNeedToSearch.push(statusAfterHandle);
statusColorMap[statusAfterHandle] = 1;
statusLevelMap[statusAfterHandle] = statusLevelMap[statusToHandle] + 1;
statusUpNodeMap[statusAfterHandle] = statusToHandle;
statusMoveMap[statusAfterHandle].x = i%4 + 1;
statusMoveMap[statusAfterHandle].y = i/4 + 1;
if (isOK(statusAfterHandle)) {
printf("%d\n", statusLevelMap[statusAfterHandle]);
printTrace(statusAfterHandle);
return;
}
}
}
statusColorMap[statusToHandle] = 2;
}
}
void handle(int status) {
if (isOK(status)) {
printf("0\n");
return;
}
searchMethod(status);
}
int main() {
// getHandleOP();
for (int i = 0; i <=3; i++) {
scanf("%s", *(initStatus + i));
}
handle(getStatusId(initStatus));
#include <queue>
#include <cstring>
#include <cmath>
#include <string>
#include <stack>
using namespace std;
const int statusNum = 1024*64; //
char initStatus[4][4];
int handleOP[16] = {4383, 8751, 17487, 34959,
4593, 8946, 17652, 35064,
7953, 12066, 20292, 36744,
61713, 61986, 62532, 63624}; // xor
char statusColorMap[statusNum]; // 0: white, 1: grey, 2: black
char statusLevelMap[statusNum];
int statusUpNodeMap[statusNum];
struct move{
int x;
int y;
};
struct move statusMoveMap[statusNum];
// void printStatus(bool status[4][4]) {
// printf("=============================\n");
// for (int i = 0; i <= 3; i++) {
// for(int j = 0; j <=3; j++) {
// printf("%d", status[i][j]);
// }
// printf("\n");
// }
// printf("=============================\n");
// }
// void handleStatus(bool status[4][4], int i, int j) {
// status[i][j] = !status[i][j];
// for (int a = 0; a <= 3; a++) {
// status[a][j] = !status[a][j];
// }
// for (int b = 0; b <= 3; b++) {
// status[i][b] = !status[i][b];
// }
// }
// int getStatusId(bool status[4][4]) {
// int id = 0;
// for(int i = 0; i <= 3; i++) {
// for(int j = 0; j <= 3; j++) {
// id += status[i][j] * pow(2, (j + i*4));
// }
// }
// return id;
// }
int getStatusId(char status[4][4]) {
int id = 0;
for(int i = 0; i <= 3; i++) {
for(int j = 0; j <= 3; j++) {
if (status[i][j] == '+') {
id += pow(2, (j + i*4));
}
}
}
return id;
}
// void getHandleOP() {
// bool status[4][4] = {0};
// for(int i = 0; i <= 3; i++) {
// for (int j = 0; j <= 3; j++) {
// memset((void *)status, 0, sizeof(bool)*16);
// handleStatus(status, i, j);
// // printStatus(status);
// printf("%d\n", getStatusId(status));
// }
// }
// }
bool isOK(int status) {
if (status == 0) {
return true;
}
return false;
}
void printTrace(int finalStatus) {
int nextStatus = finalStatus;
stack<string> traceStack;
while(statusUpNodeMap[nextStatus] != -1) {
char trace[5] = "";
// printf("%d %d\n", statusMoveMap[nextStatus].x, statusMoveMap[nextStatus].y);
sprintf(trace, "%d %d\n", statusMoveMap[nextStatus].y, statusMoveMap[nextStatus].x);
traceStack.push(string(trace));
nextStatus = statusUpNodeMap[nextStatus];
}
while(!traceStack.empty()) {
printf("%s", traceStack.top().c_str());
traceStack.pop();
}
}
void searchMethod(int status) {
statusUpNodeMap[status] = -1;
statusLevelMap[status] = 0;
statusColorMap[status] = 1;
queue<int> statusNeedToSearch;
statusNeedToSearch.push(status);
while(1) {
if (statusNeedToSearch.size() == 0) {
printf("Impossible\n");
return;
}
int statusToHandle = statusNeedToSearch.front();
statusNeedToSearch.pop();
for(int i = 0; i <= 15; i++) {
int statusAfterHandle = statusToHandle^handleOP[i];
if (statusColorMap[statusAfterHandle] == 0) {
statusNeedToSearch.push(statusAfterHandle);
statusColorMap[statusAfterHandle] = 1;
statusLevelMap[statusAfterHandle] = statusLevelMap[statusToHandle] + 1;
statusUpNodeMap[statusAfterHandle] = statusToHandle;
statusMoveMap[statusAfterHandle].x = i%4 + 1;
statusMoveMap[statusAfterHandle].y = i/4 + 1;
if (isOK(statusAfterHandle)) {
printf("%d\n", statusLevelMap[statusAfterHandle]);
printTrace(statusAfterHandle);
return;
}
}
}
statusColorMap[statusToHandle] = 2;
}
}
void handle(int status) {
if (isOK(status)) {
printf("0\n");
return;
}
searchMethod(status);
}
int main() {
// getHandleOP();
for (int i = 0; i <=3; i++) {
scanf("%s", *(initStatus + i));
}
handle(getStatusId(initStatus));
}
跟1753 基本一样, 就是结束条件更严格. 注意输出的格式 其实 是 y x (a row number and a column number)
果然清楚了以后明显写的明显快了。
还是用的位操作来进行快速的handler数组操作, 注释的部分是用来求相应的异或操作数。
除了要求出操作次数,本题还要求取出操作的步骤,
建了两个表来保存每一个status的上一个status, 以及到此status进行的 x y 操作。
在得到最终的status以后, 根据这两个表回溯, 最后加一个栈来实现顺序输出。
其实可以把这两个表合成一个 struct表。
还有, 保存status的要是int, 不然溢出。