#include <iostream>
#include <fstream>
#include <queue>
#include <cmath>
using namespace std;
const int MAX = 10;
int best[MAX][MAX]; //机器人位置
int m, n; //矩阵为 m * n
int bestk; //机器人个数
int dx[] = {0, 1, -1, 0, 0}; //原位置及四个方向
int dy[] = {0, 0, 0, 1, -1};
void print(int a[MAX][MAX])
{
for(int i=0; i<=m+1; i++)
{
for(int j=0; j<=n+1; j++)
cout << a[i][j];
cout << endl;
}
}
class Node
{
public:
int i, j; //当前所考察方格的位置
int k; //机器人个数
int t; //被监视的方格个数
int board[MAX][MAX]; //记录方格被监视情况
int root[MAX][MAX]; //记录机器人位置
Node(int ii, int jj)
{
i = ii;
j = jj;
k = t = 0;
}
//机器人个数小的先出队列
bool operator < (const Node &node) const
{
return k >= node.k;
}
};
priority_queue<Node> q;
template<class Type>
void copy2(Type src[MAX][MAX], Type des[MAX][MAX])
{
for(int i=0; i<=m+1; i++)
for(int j=0; j<=n+1; j++)
des[i][j] = src[i][j];
}
//在i, j位置设置一个机器人,并改变周围陈列室受监视的状态
//向优先队列中加入结点
void change(Node enode, int i, int j)
{
Node now(enode.i, enode.j);
now.t = enode.t; //被监视的方格个数
now.k = enode.k; //机器人个数
copy2(enode.board, now.board); //cout << enode.board[1][1] << " " << now.board[1][1];
copy2(enode.root, now.root);
now.root[i][j] = 1; //放置机器人
now.k++;
for(int d=0; d<=4; d++) //原位置及周围被监视
{
int p = i + dx[d];
int q = j + dy[d];
now.board[p][q]++;
if(now.board[p][q] == 1)
now.t++;
}
while(now.board[now.i][now.j] && now.i<=n)
{
now.j++;
if(now.j>n)
{
now.i++;
now.j = 1;
}
}
q.push(now);
}
void search()
{
Node enode(1, 1);
for(int a=0; a<=m+1; a++) //初始化
{
for(int b=0; b<=n+1; b++)
{
enode.board[a][b] = 0;
enode.root[a][b] = 0;
}
}
for(a=0; a<=m+1; a++) //最外圈一层为1
{
enode.board[a][0] = 1;
enode.board[a][n+1] = 1;
}
for(a=0; a<=n+1; a++)
{
enode.board[0][a] = 1;
enode.board[m+1][a] = 1;
}
int i, j;
while(true)
{
i = enode.i;
j = enode.j;
if(enode.t == n*m)
{
bestk = enode.k;
copy2(enode.root, best);
break;
}
else
{
if(i < m)
change(enode, i+1, j);
if(j<n && (enode.board[i][j+1]==0 || enode.board[i][j+2]==0))
change(enode, i, j+1);
if(enode.board[i+1][j]==0 && enode.board[i][j+1]==0)
change(enode, i, j);
}
if(q.empty())
break;
else
{
enode = q.top();
q.pop();
}
}
}
int main()
{
ifstream fin("名画陈列馆.txt");
cout << "输入矩阵行数:";
fin >> m; cout << m << endl;
cout << "输入矩阵列数:";
fin >> n; cout << n << endl;
search();
cout << "最少的机器人个数为:" << bestk << endl;
cout << "机器人位置为:\n";
for(int i=1; i<=m; i++)
{
for(int j=1; j<=n; j++)
cout << best[i][j] << "\t";
cout << endl;
}
cout << endl;
fin.close();
return 0;
}
世界名画陈列馆问题
最新推荐文章于 2022-11-02 19:35:40 发布