游戏规则
这是一个多轮游戏。
给你一个20×4020×40 的地图。
地图中有n 个鬼,11 个吃豆人,若干墙,若干豆子。
鬼的个数由地图判断。目前保证小于等于两个。
鬼和吃豆人只会向上下左右四个方向移动,每轮移动一格,吃豆人先移动然后鬼移动,并且不会走到地图之外。
鬼和吃豆人都不能穿墙而行。换句话说,如果某个地方是一堵墙,那么吃豆人和鬼都不能走到那个地方。
当以下任意一个条件成立,那么本场游戏结束,开始下一场游戏。
- 吃豆人被鬼抓住了
- 游戏进行了 99 轮
吃豆人每吃到一个豆子,就会得到 1
分,所有场景全部结束后,争取最大化总得分。
交互规则
每轮中您可以访问 ai,j 数组,其中下标 i 的范围是 1-20,下标 j 的范围是 1-40,ai,j 数组中的数值表示地图状态如下:
0
表示,空地,表示当前位置没有任何元素。1
表示,吃豆人,表示这就是您能控制的吃豆人所在位置。保证吃豆人数量唯一。2
表示,豆子,表示当前位置有一颗豆子。吃了它,您可以得一分。4
表示,墙,表示一堵墙。您和鬼都不可以到达的地方。8
表示,鬼,当前鬼所在地。对于不同的地图,鬼有自己的策略来尽量阻碍吃豆人吃豆子。10
表示,鬼和豆子。此地有鬼,也有豆子。在吃掉这颗豆子之前,你会被鬼吃掉。
接下来您需要根据这些信息返回 U
D
L
R
, 来控制吃豆人的移动,分别表示上下左右。注意每次抉择只能返回其中一个字母。并且是大写的。
更正式的,假设当前吃豆人的位置为(x,y),那么做出以下决定的吃豆人移动情况如下。
注意事项
您只需要solve() 函数里面编写您的策略并且返回对吃豆人的操作即可。
祝您游玩愉快。
参考实现代码
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 50;
int a[N][N];
const int szx = 20;
const int szy = 40;
string s;
void get_map(string mp){
//cin >> mp;
for(int i = 1;i <= szx;i ++)
for (int j = 1;j <= szy;j ++){
int pos = (i - 1) * szy + j;
pos --;
int st = mp[pos] - '0';
a[i][j] = st;
}
return;
}
pair<int,int> get_ghost_pos1(string p){
int x1 = (p[0] - '0') * 10 + p[1] - '0';
int y1 = (p[2] - '0') * 10 + p[3] - '0';
return {x1 ,y1};
}
pair<pair<int,int>,pair<int,int>> get_ghost_pos2(string p){
int x1 = (p[0] - '0') * 10 + p[1] - '0';
int y1 = (p[2] - '0') * 10 + p[3] - '0';
int x2 = (p[4] - '0') * 10 + p[5] - '0';
int y2 = (p[6] - '0') * 10 + p[7] - '0';
return {{x2, y2},{x1 ,y1}};
}
pair<int,int> preghost1;
pair< pair<int,int>, pair<int,int> > preghost2;
int person_x = 0;
int person_y = 0;
void init_mp(){
get_map(s);
int cnt = 0;
for(int i = 1;i <= szx;i ++){
for(int j = 1;j <= szy;j ++){
if(a[i][j] == 5) a[i][j] = 8;
if(a[i][j] == 6) a[i][j] = 10;
if(a[i][j] & 1) {
person_x = i; //
person_y = j; //
}
if((a[i][j] >> 3) & 1){
if(cnt == 0){
preghost1.first = i;
preghost1.second = j;
cnt ++;
}else{
preghost2.first = preghost1;
preghost2.second.first = i;
preghost2.second.second = j;
}
}
}
}
}
void react_ghost(){
if(s.size() == 8){
auto ghost = get_ghost_pos2(s);
int x1 = preghost2.first.first;
int y1 = preghost2.first.second;
int x2 = preghost2.second.first;
int y2 = preghost2.second.second;
a[x1][y1] ^= (1ll << 3);
a[x2][y2] ^= (1ll << 3);
a[ghost.first.first][ghost.first.second] ^= (1ll << 3);
a[ghost.second.first][ghost.second.second] ^= (1ll << 3);
preghost2 = ghost;
}
else if(s.size() == 4){
int x = preghost1.first;
int y = preghost1.second;
a[x][y] ^= (1ll << 3);
auto ghost = get_ghost_pos1(s);
a[ghost.first][ghost.second] ^= (1ll << 3);
preghost1 = ghost;
}
}
int seed = 135;
int nowv = 0;
const int mod = 1e9 + 7;
int my_rand(int l,int r){
nowv += seed;
nowv %= mod;
nowv = (nowv * nowv) % mod;
nowv += (5 * seed)/ 3;
nowv %= mod;
return (nowv % (r - l + 1) + l);
}
void D(){
a[person_x][person_y] ^= 1;
person_x ++;
a[person_x][person_y] ^= 1;
cout << "D" << endl;
}
void U(){
a[person_x][person_y] ^= 1;
person_x --;
a[person_x][person_y] ^= 1;
cout << "U" << endl;
}
void L(){
a[person_x][person_y] ^= 1;
person_y --;
a[person_x][person_y] ^= 1;
cout << "L" << endl;
}
void R(){
a[person_x][person_y] ^= 1;
person_y ++;
a[person_x][person_y] ^= 1;
cout << "R" << endl;
}
/*
你的策略
如果你需要写递归,可以在solve函数之前添加你的递归函数并在solve函数中调用。
*/
char solve()
{
/* 不要改动a数组的信息!
a[i][j] = 0 时 为空地
a[i][j] = 1 时 为人
a[i][j] = 2 时 为豆子
a[i][j] = 4 时 为墙
a[i][j] = 8 时 为鬼
a[i][j] = 10 时 为鬼和豆子
不要改动person_x,person_y变量!
person_x 是吃豆人的x坐标
person_y 是吃豆人的y坐标
*/
/*
以下示例程序是随机程序
如果随机到 1 则返回 U
如果随机到 2 则返回 D
如果随机到 3 则返回 R
如果随机到 4 则返回 L
*/
int op = my_rand(1,4);
if(op == 1){
return 'U';
}
else if(op == 2)return 'D';
else if(op == 3) return 'R';
else return 'L';
return 'D';
}
signed main() {
while(cin >> s){
if(s.size() >= 40){
init_mp();
}
else {
react_ghost();
}
char x = solve();
if(x == 'U'){
U();
}
else if(x == 'L'){
L();
}
else if(x == 'R'){
R();
}
else D();
if((a[person_x][person_y] >> 1) & 1){
a[person_x][person_y] ^= (1ll << 1);
}
}
return 0;
}
代码参考
#include <bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N = 50;
int a[N][N];
const int szx = 20;
const int szy = 40;
string s;
int person_x = 0, person_y = 0;
queue<char> move_queue; // 保存下一步的移动方向
void get_map(string mp) {
for (int i = 1; i <= szx; i++)
for (int j = 1; j <= szy; j++) {
int pos = (i - 1) * szy + j;
pos--;
int st = mp[pos] - '0';
a[i][j] = st;
}
return;
}
pair<int, int> get_ghost_pos1(string p) {
int x1 = (p[0] - '0') * 10 + p[1] - '0';
int y1 = (p[2] - '0') * 10 + p[3] - '0';
return {x1, y1};
}
pair<pair<int, int>, pair<int, int>> get_ghost_pos2(string p) {
int x1 = (p[0] - '0') * 10 + p[1] - '0';
int y1 = (p[2] - '0') * 10 + p[3] - '0';
int x2 = (p[4] - '0') * 10 + p[5] - '0';
int y2 = (p[6] - '0') * 10 + p[7] - '0';
return {{x2, y2}, {x1, y1}};
}
pair<int, int> preghost1;
pair<pair<int, int>, pair<int, int>> preghost2;
void init_mp() {
get_map(s);
int cnt = 0;
for (int i = 1; i <= szx; i++) {
for (int j = 1; j <= szy; j++) {
if (a[i][j] == 5) a[i][j] = 8;
if (a[i][j] == 6) a[i][j] = 10;
if (a[i][j] & 1) {
person_x = i;
person_y = j;
}
if ((a[i][j] >> 3) & 1) {
if (cnt == 0) {
preghost1 = {i, j};
cnt++;
} else {
preghost2 = {{i, j}, preghost1};
preghost1 = {i, j};
}
}
}
}
}
void react_ghost() {
if (s.size() == 8) {
auto ghost = get_ghost_pos2(s);
int x1 = preghost2.first.first;
int y1 = preghost2.first.second;
int x2 = preghost2.second.first;
int y2 = preghost2.second.second;
a[x1][y1] ^= (1ll << 3);
a[x2][y2] ^= (1ll << 3);
a[ghost.first.first][ghost.first.second] ^= (1ll << 3);
a[ghost.second.first][ghost.second.second] ^= (1ll << 3);
preghost2 = ghost;
} else if (s.size() == 4) {
int x = preghost1.first;
int y = preghost1.second;
a[x][y] ^= (1ll << 3);
auto ghost = get_ghost_pos1(s);
a[ghost.first][ghost.second] ^= (1ll << 3);
preghost1 = ghost;
}
}
void D() {
a[person_x][person_y] ^= 1;
person_x++;
a[person_x][person_y] ^= 1;
cout << "D" << endl;
}
void U() {
a[person_x][person_y] ^= 1;
person_x--;
a[person_x][person_y] ^= 1;
cout << "U" << endl;
}
void L() {
a[person_x][person_y] ^= 1;
person_y--;
a[person_x][person_y] ^= 1;
cout << "L" << endl;
}
void R() {
a[person_x][person_y] ^= 1;
person_y++;
a[person_x][person_y] ^= 1;
cout << "R" << endl;
}
bool is_safe(int x, int y) {
return x > 0 && x <= szx && y > 0 && y <= szy && a[x][y] != 4 && a[x][y] != 8 && a[x][y] != 10;
}
int heuristic(int x1, int y1, int x2, int y2) {
return abs(x1 - x2) + abs(y1 - y2);
}
vector<pair<int, int>> bfs_find_path(int start_x, int start_y, int goal_x, int goal_y) {
queue<tuple<int, int, vector<pair<int, int>>>> q;
vector<vector<bool>> visited(szx + 1, vector<bool>(szy + 1, false));
vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
q.push({start_x, start_y, {}});
visited[start_x][start_y] = true;
while (!q.empty()) {
auto [x, y, path] = q.front();
q.pop();
path.push_back({x, y});
if (x == goal_x && y == goal_y) {
return path;
}
for (auto [dx, dy] : directions) {
int nx = x + dx, ny = y + dy;
if (is_safe(nx, ny) && !visited[nx][ny]) {
visited[nx][ny] = true;
q.push({nx, ny, path});
}
}
}
return {};
}
char solve() {
vector<pair<int, int>> beans;
for (int i = 1; i <= szx; i++) {
for (int j = 1; j <= szy; j++) {
if (a[i][j] == 2) {
beans.push_back({i, j});
}
}
}
if (beans.empty()) {
vector<pair<int, int>> directions = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
vector<char> possible_moves;
for (auto [dx, dy] : directions) {
int nx = person_x + dx, ny = person_y + dy;
if (is_safe(nx, ny)) {
if (dx == -1) possible_moves.push_back('U');
if (dx == 1) possible_moves.push_back('D');
if (dy == -1) possible_moves.push_back('L');
if (dy == 1) possible_moves.push_back('R');
}
}
if (!possible_moves.empty()) {
return possible_moves[rand() % possible_moves.size()];
}
return 'L';
}
pair<int, int> closest_bean = beans[0];
int min_dist = INT_MAX;
for (auto [bx, by] : beans) {
int dist = heuristic(person_x, person_y, bx, by);
if (dist < min_dist) {
min_dist = dist;
closest_bean = {bx, by};
}
}
vector<pair<int, int>> path = bfs_find_path(person_x, person_y, closest_bean.first, closest_bean.second);
if (path.size() > 1) {
pair<int, int> next_step = path[1];
if (next_step.first == person_x - 1) return 'U';
if (next_step.first == person_x + 1) return 'D';
if (next_step.second == person_y - 1) return 'L';
if (next_step.second == person_y + 1) return 'R';
}
return 'L';
}
signed main() {
while(cin >> s) {
if(s.size() >= 40) {
init_mp();
} else {
react_ghost();
}
char x = solve();
switch(x) {
case 'U': U(); break;
case 'L': L(); break;
case 'R': R(); break;
default: D(); break;
}
if((a[person_x][person_y] >> 1) & 1) {
a[person_x][person_y] ^= (1ll << 1);
}
}
return 0;
}