题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4093
题意:题意基于ZOJ4092题意的基础上,给一个12*12的矩阵,矩阵中值为1的即这个点是墙,为0即为空地,为2即为空地上有一个垃圾。现在有6种操作,'U','D','L','R',表示向上下左右四个方向移动一步,如果下一步是墙就留在原地,'I'是停留原地,'P'表示捡起地上的垃圾,若地上无垃圾则不做操作,一个地方如果本来有垃圾后被拿走,那么值由2变到0,现在有一个长度为243的指令序列,若当前处于(i,j)位置上,那么定义x = 81*m[i][j]+27*m[i-1][j]+9*m[i+1][j]+3*m[i][j-1]+1*m[i][j+1],然后取指令序列的第x+1个指令进行操作。题目没有输入,后台数据会给出1000个这样的矩阵,保证只有周围一圈是墙,里面10*10的矩阵都是0或2,且各50个,随机等概率分布,现在题目要求一个长为243的指令序列,使得这一千个矩阵(人走的起点均为(2,2))中各走两百步之后所能捡到的垃圾数不小于原垃圾总数的95%
思路:首先,可以发现‘I’这个指令啥用没有,然后发现可以从1~243遍历这个指令序列,每一个序号只对应一种情况,比如3号指令,一定对应当前位为0,上下左均为0,右边为2的情况(如下图)这样一个位置(对81取模,再对27取模...得到)
0 | ||
0 | 0 | 2 |
0 |
那么可以得出第i个指令的规律:
1.i/81 == 1时,该种情况不可能出现,指令任意即可
2.i/81 == 2时,当前有垃圾,一定是先捡垃圾更优,所以指令为‘P’
3.i/81==0时,再进行分类:
若该情况是四个方向上有1的,那么即是沿着墙的,先暂定(10*10)沿墙顺时针走,在此基础上,若沿墙走的点周围有 垃圾,先往有垃圾的方向走。
若位置周围全都是空地,那么就默认往右走
若位置周围超过一个地方有垃圾,那么方向的选择顺序为上右左下
代码:
#include<iostream>
#include <cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<functional>
#include <unordered_map>
#include<queue>
#include<cmath>
#include<unordered_map>
#include<fstream>
#include<ctime>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
char s[500];
int n = 12;
int main()
{
memset(s, 0, sizeof(0));
for (int i = 1; i <= 243; i++)
{
s[i] = 'P';
}
for (int j = 1; j <= 243; j++)
{
int k[5];
int i = j;
memset(k, 0, sizeof(k));
if (i / 81)continue;
if (i/27)//上
{
if (i / 27 == 2)
{
s[j] = 'U';
continue;
}
else
k[0] = 1;
}
i = j % 3;//右
if (i == 2)
{
s[j] = 'R';
continue;
}
if (i == 1)
k[3] = 1;
i = j%9;//左
if (i / 3)
{
if (i / 3 == 2)
{
s[j] = 'L';
continue;
}
else
k[2] = 1;
}
i = j % 27;//下
if (i / 9)
{
if (i / 9 == 2)
{
s[j] = 'D';
continue;
}
else
k[1] = 1;
}
if (k[0] && k[1])
{
s[j] = 'R';
}
else if(k[2] && k[1])
{
s[j] = 'U';
}
else if(k[0] && k[3])
{
s[j] = 'D';
}
else if (k[1] && k[3])
{
s[j] = 'L';
}
else if (k[0])
{
s[j] = 'R';
}
else if (k[3])
{
s[j] = 'D';
}
else if (k[1])
{
s[j] = 'L';
}
else if (k[2])
{
s[j] = 'U';
}
else
{
s[i] = 'R';
}
}
s[244] = '\0';
for (int i = 243; i > 1; i--)
s[i] = s[i - 1];
s[1] = 'R';
printf("%s\n", s + 1);
}