利用分支限界法给出解决下面题目的C++代码 。题目描述 Griseo是黄金庭园的团宠小画家,最近她又开始了她的创作。 由于Griseo画工强大,所以她只需要在画布(视为 n*m的二维平面,坐标起始点为1)的某处点上一 笔,颜料就会依照Griseo的想法无尽扩散,颜料的扩散方式是这样的: 1、初始时颜料会向上扩散; 2、每个小时,颜料会根据Griseo的想法扩散s[i]的距离; 3、当该小时结束后,颜料将分裂成两部分,各向45o方向移动; Griseo想知道在每个小时末颜料的覆盖范围,以此推测画作的模样。 输入输出格式 输入 第一行包含三个整数 n、m 、t,代表画布大小和颜料扩散时间; 第二行包含t 个整数 s1、s2 、… st ,代表第i个小时颜料扩散的距离; 第三行包含两个整数 x、y代表颜料的初始位置。 输出 输出为一行,包含t个整数,第i个整数代表第i个小时末画布上颜料的覆盖范围。 数据范围 1<=n,m<=500,1<=t<=24 1<=si<=13 1<=x<=n,1<=y<=m、
时间: 2023-06-27 10:07:17 浏览: 82
以下是分支限界法解决该问题的C++代码:
```c++
#include <iostream>
#include <cstring>
#include <queue>
using namespace std;
const int N = 510, T = 25;
int n, m, t;
int s[T];
int x, y;
int ans[T];
bool st[N][N][T][8]; // 判断是否访问过该状态
struct Node
{
int x, y, hour, dir;
Node(int a, int b, int c, int d): x(a), y(b), hour(c), dir(d) {}
};
void bfs()
{
queue<Node> q;
q.push(Node(x, y, 0, 0));
st[x][y][0][0] = true; // 标记初始状态已访问
while (!q.empty())
{
auto t = q.front();
q.pop();
if (t.hour == t) // 如果已经扩散到第t个小时
ans[t.hour]++; // 统计答案
int dx[] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dy[] = {0, 1, 1, 1, 0, -1, -1, -1};
// 8个方向,依次为:左上、右上、右、右下、下、左下、左、左上
// 扩散
if (t.hour < t) // 如果还没扩散到第t个小时
{
for (int i = 0; i <= t.dir; i++) // 扩散距离为s[i]
{
int nx = t.x + dx[i], ny = t.y + dy[i];
if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && !st[nx][ny][t.hour+1][i])
{
st[nx][ny][t.hour+1][i] = true;
q.push(Node(nx, ny, t.hour+1, i));
}
}
}
// 分裂
if (t.hour < t-1) // 如果不是最后一次分裂
{
int nd = (t.dir + 1) % 8; // 顺时针旋转45度
int nx = t.x + dx[nd], ny = t.y + dy[nd];
if (nx >= 1 && nx <= n && ny >= 1 && ny <= m && !st[nx][ny][t.hour+1][nd])
{
st[nx][ny][t.hour+1][nd] = true;
q.push(Node(nx, ny, t.hour+1, nd));
}
}
}
}
int main()
{
cin >> n >> m >> t;
for (int i = 1; i <= t; i++) cin >> s[i];
cin >> x >> y;
bfs();
for (int i = 1; i <= t; i++) cout << ans[i] << " ";
return 0;
}
```
阅读全文