Time Limit: 1 secs, Memory Limit: 32 MB
The game of ‘Inverso’ is played on a 3x3 grid of colored fields (each field is either black or white). Each field is numbered as follows:
1 2 3
4 5 6
7 8 9
The player can click on a field, which will result in the inversion of that field and all its direct neighboring fields (i.e. the color changes from black to white or vice-versa). Hence,
Clicking field 1 inverts fields 1, 2, 4, 5
Clicking field 2 inverts fields 1, 2, 3, 4, 5, 6
Clicking field 3 inverts fields 2, 3, 5, 6
Clicking 4 inverts fields 1, 2, 4, 5, 7, 8
Clicking 5 inverts fields all fields
Clicking 6 inverts fields 2, 3, 5, 6, 8, 9
Clicking 7 inverts fields 4, 5, 7, 8
Clicking 8 inverts fields 4, 5, 6, 7, 8, 9
Clicking 9 inverts fields 5, 6, 8, 9
The aim of the game is to find the shortest sequence of clicks to make all fields white from a given start coloring of the grid.
The first line contains a number N (0≤N≤10000) of runs. The following N lines each contain a string of nine letters ‘b’ (black) or ‘w’ (white) for the color of the fields 1 to 9. This is the initial coloring of the grid.
For each input string the shortest word in the letters ‘1’… ‘9’ (for clicking field one, …, nine) which makes all fields white. If there is more than one shortest word then the lexicographically smallest one must be printed (‘1234’ is smaller than ‘1342’).
3 bbwbwbwbw bwwwbwbwb bbbbwbbbw
2459 267 356789
题目分析
题目大意是:9宫格,点击不同位置会翻转直接相连的格子,求最短路径使其翻为全白
所谓的最短路径是1步骤最少,2步骤相同时要求数字最小
一开始以为步骤相同时获得的解法可能是乱序的,引入一个dim变量来判断
当格子全白时,
如果dim为0,将此时解法的长度赋给dim,
否则
此时解法的长度==dim,则判断是否要更新解法,
否则可以退出搜索(之后的解法长度都将大于dim)
题目最坑的是如果一开始就是全白要输出"11"
后来再想,其实只要按照数字顺序去翻转,获得的解法必然是升序的,这样只要取第一个即可,
试了下,AC
#include <cstdio> #include <iostream> #include <queue> #include <vector> #include <algorithm> std::vector<std::string> visited; int rule[9][9] = {1,1,0,1,1,0,0,0,0, 1,1,1,1,1,1,0,0,0, 0,1,1,0,1,1,0,0,0, 1,1,0,1,1,0,1,1,0, 1,1,1,1,1,1,1,1,1, 0,1,1,0,1,1,0,1,1, 0,0,0,1,1,0,1,1,0, 0,0,0,1,1,1,1,1,1, 0,0,0,0,1,1,0,1,1}; char change(char c) { if (c == 'w') return 'b'; return 'w'; } bool unvisited(std::string data) { std::vector<std::string>::iterator it = find(visited.begin(), visited.end(), data); return it == visited.end(); } int main() { std::string target = "wwwwwwwww"; int cases; scanf("%d", &cases); while (cases--) { std::string init; std::cin >> init; if (init == target) { printf("11\n"); continue; } std::queue<int> solution; std::queue<std::string> paths; paths.push(init); solution.push(0); if (!visited.empty()) visited.clear(); visited.push_back(init); int ans = 0; bool flag = true; while (!paths.empty() && flag) { std::string nowpath = paths.front(); paths.pop(); int nowsol = solution.front(); solution.pop(); for (int i = 0; i < 9; ++i) { std::string temp = nowpath; for (int j = 0; j < 9; ++j) if (rule[i][j]) temp[j] = change(temp[j]); int newsol = nowsol*10 + i+1; if (temp == target) { ans = newsol; flag = false; break; } if (unvisited(temp)) { paths.push(temp); solution.push(newsol); visited.push_back(temp); } } } printf("%d\n", ans); } }