#include<iostream>
#include<vector>
#include<string>
using namespace std;
void chushihua(int r,int c,vector<string> &result,vector< vector<int> > &newresult,vector<vector<int> > &noplace){
for(int i=0;i<r*c;i++){
if(result[0][i]=='X'){
newresult[i/c][i%c]=7;
noplace[i/c][i%c]=1;
}
else if(result[0][i]=='0'){
newresult[i/c][i%c]=0;
noplace[i/c][i%c]=1;
}
else if(result[0][i]=='1'){
newresult[i/c][i%c]=1;
noplace[i/c][i%c]=1;
}
else if(result[0][i]=='2'){
newresult[i/c][i%c]=2;
noplace[i/c][i%c]=1;
}
else if(result[0][i]=='3'){
newresult[i/c][i%c]=3;
noplace[i/c][i%c]=1;
}
else if(result[0][i]=='4'){
newresult[i/c][i%c]=4;
noplace[i/c][i%c]=1;
}
else{
newresult[i/c][i%c]=6;
noplace[i/c][i%c]=0;
}
}
}
// 放置灯的函数(4方向,光线遇到墙壁 7 或数字 0~4 停止)
void placeLight(int r, int c, vector<vector<int> >& newresult, vector<vector<int> >& noplace) {
int rows = newresult.size();
if (rows == 0) return;
int cols = newresult[0].size();
// 检查是否可以放灯:必须是空地 6,且当前允许放置(noplace == 0)
if (r < 0 || r >= rows || c < 0 || c >= cols) return;
if (newresult[r][c] != 6 || noplace[r][c] != 0) return;
// 放置灯
newresult[r][c] = 5; // 5 代表灯
// 四个方向:上(-1,0)、下(1,0)、左(0,-1)、右(0,1)
int dr[] = {-1, 1, 0, 0};
int dc[] = {0, 0, -1, 1};
for (int d = 0; d < 4; ++d) {
int dir_r = dr[d];
int dir_c = dc[d];
int nr = r + dir_r;
int nc = c + dir_c;
while (true) {
// 越界,停止
if (nr < 0 || nr >= rows || nc < 0 || nc >= cols) {
break;
}
int cell = newresult[nr][nc];
// 遇到墙壁 7 或数字 0~4,光线停止
if (cell == 7 || (cell >= 0 && cell <= 4)) {
break;
}
// 如果是可放置的空格 6,则在 noplace 中标记为不能放灯
if (cell == 6) {
noplace[nr][nc] = 1;
}
// 沿当前方向继续前进
nr += dir_r;
nc += dir_c;
}
}
}
// 获取 (r,c) 的上下左右 4 个邻居,存入 neighbors(每个元素是 pair<int,int>)
void getNeighbors(int r, int c, int rows, int cols, vector<pair<int, int> >& neighbors) {
int dr[] = {-1, 1, 0, 0}; // 上,下
int dc[] = {0, 0, -1, 1}; // 左,右
for (int d = 0; d < 4; d++) {
int nr = r + dr[d];
int nc = c + dc[d];
if (nr >= 0 && nr < rows && nc >= 0 && nc < cols) {
neighbors.push_back(make_pair(nr, nc));
}
}
}
void canreason(int rows, int cols, vector<vector<int> >& newresult, vector<vector<int> >& noplace) {
// ===== 规则 1:如果数字是 4,就往上下左右放灯(如果可放)=====
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (newresult[i][j] == 4) {
vector<pair<int, int> > neighbors;
getNeighbors(i, j, rows, cols, neighbors);
vector<pair<int, int> > available_spots;
// 遍历 4 个邻居
for (int k = 0; k < neighbors.size(); k++) {
pair<int, int> p = neighbors[k];
int nr = p.first;
int nc = p.second;
int val = newresult[nr][nc];
if (val == 6 && noplace[nr][nc] == 0 && val != 5 && val != 7) {
available_spots.push_back(make_pair(nr, nc));
}
}
// 如果刚好有 4 个可放的空位,就都放灯
if (available_spots.size() == 4) {
for (int k = 0; k < available_spots.size(); k++) {
pair<int, int> p = available_spots[k];
int nr = p.first;
int nc = p.second;
placeLight(nr, nc, newresult, noplace);
}
}
}
}
}
// ===== 规则 2:如果数字是 0~3,且已放的灯数 == 数字,则放周围可放的空位 =====
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int num = newresult[i][j];
if (num >= 0 && num <= 3) {
vector<pair<int, int> > neighbors;
getNeighbors(i, j, rows, cols, neighbors);
int light_count = 0;
vector<pair<int, int> > available_spots;
for (int k = 0; k < neighbors.size(); k++) {
pair<int, int> p = neighbors[k];
int nr = p.first;
int nc = p.second;
int val = newresult[nr][nc];
if (val == 5) {
light_count++;
} else if (val == 6 && noplace[nr][nc] == 0 && val != 5 && val != 7) {
available_spots.push_back(make_pair(nr, nc));
}
}
if (light_count == num) {
for (int k = 0; k < available_spots.size(); k++) {
pair<int, int> p = available_spots[k];
int nr = p.first;
int nc = p.second;
placeLight(nr, nc, newresult, noplace);
}
}
}
}
}
// ===== 规则 3(可选):如果一个空位 6 周围没有灯,就放灯 =====
// 你可以后续加上
}
// 检查是否游戏结束(noplace全为1,且所有数字满足灯数,且灯之间不冲突)
bool ifEnd(int rows, int cols, vector<vector<int> >& newresult, vector<vector<int> >& noplace) {
// ===== 第一步:检查 noplace 是否全为 1(即没有可放灯的空位了)=====
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (noplace[i][j] == 0&&newresult[i][j]==6) {
// 只要有一个格子还能放灯(noplace == 0),就不是结束状态
return false;
}
}
}
// ===== 第二步:检查每个数字(0~4)周围 4 方向的灯(5)的数量是否等于该数字 =====
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
int val = newresult[i][j];
if (val >= 0 && val <= 4) { // 是数字
int expected = val; // 期望的灯数量
int actual = 0;
// 检查上下左右 4 个方向
int dr[] = {-1, 1, 0, 0};
int dc[] = {0, 0, -1, 1};
for (int d = 0; d < 4; d++) {
int nr = i + dr[d];
int nc = j + dc[d];
if (nr >= 0 && nr < rows && nc >= 0 && nc < cols) {
if (newresult[nr][nc] == 5) { // 是灯
actual++;
}
}
}
if (actual != expected) {
return false; // 数字对应的灯数量不对
}
}
}
}
// ===== 第三步:检查任意两盏灯(5)之间不能无阻挡地看到对方(即不能相互照亮)=====
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (newresult[i][j] == 5) { // 当前是灯
int dr[] = {-1, 1, 0, 0};
int dc[] = {0, 0, -1, 1};
for (int d = 0; d < 4; d++) {
int nr = i + dr[d];
int nc = j + dc[d];
while (true) {
if (nr < 0 || nr >= rows || nc < 0 || nc >= cols) {
break;
}
int cell = newresult[nr][nc];
if (cell == 5) { // 另一盏灯
return false; // 两灯之间无阻挡,冲突!
}
if (cell == 7 || cell == 0 || cell == 1 || cell == 2 || cell == 3 || cell == 4) {
// 遇到墙壁或数字,挡住了,不用继续
break;
}
// 如果是空位 6,继续往前检查
nr += dr[d];
nc += dc[d];
}
}
}
}
}
// 所有条件都满足!
return true;
}
void backtrack(int k,int r,int c,vector<vector<int> >& newresult, vector<vector<int> >& noplace) {
if (k == r * c) {
if (ifEnd(r, c, newresult, noplace)) { // ? ifEnd 返回 true 才是满足条件
cout << "? 找到一个合法解!" << endl;
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
cout << newresult[i][j] << " ";
}
cout << endl;
} return;// 如果你只想找一个解,可以在这里 return;
}
else {
for (int i = 0; i < r; i++) {
for (int j = 0; j < c; j++) {
cout << newresult[i][j] << " ";
}
cout << endl;
}
cout << "? ? 遍历完所有格子,但没有找到满足条件的解。" << endl;
}
}
else if(noplace[k/c][k%c]==1||newresult[k/c][k%c]==5){
backtrack(k+1,r,c,newresult,noplace);
}
else {
vector<vector<int> >tmp1;
vector<vector<int> >tmp2;
tmp1=newresult;
tmp2=noplace;
placeLight(k/c,k%c,newresult,noplace);
canreason(r, c,newresult,noplace);
backtrack(k+1,r,c,newresult,noplace);
newresult=tmp1;
noplace=tmp2;
noplace[k/c][k%c]=1;
backtrack(k+1,r,c,newresult,noplace);
}
}
int main(){
vector<string> result;
int r,c;
cin>>r>>c;
string s;
cin>>s;
result.push_back(s);
for(int j=0;j<result.size();j++){
printf("%s\n",result[j].c_str());
}
vector<vector<int> > newresult(r,vector<int>(c));
vector<vector<int> > noplace(r,vector<int>(c));
chushihua(r,c,result,newresult,noplace);
backtrack(0,r,c,newresult,noplace);
return 0;
}为什么没有回溯的结果,只是遍历完