http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=4092
题意
给出n × m的方格,给出一串指令,机器人初始在一个位置,机器人会根据方格四周(包括自身)的值得出要执行的指令,问执行k次之后,机器人捡到了多少垃圾。
题解
k特别大,所以不能直接暴力模拟,考虑什么时候机器人会进入死循环。
因为机器人会根据四周的值计算该执行什么指令,而只有捡了垃圾才会改变方格的值,所以如果到当前点机器人捡的垃圾的个数和之前是一样的,那么就进入了死循环。(说明绕了一圈已经没有垃圾可捡了[方格的值没有改变],那只会一直对着这个绕圈)
代码
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e3+1;
int t,n,m;
long long k;
char s[300];
char mat[maxn][maxn];
int vis[maxn*10];
int f_pow(int a,int b){
int res = 1;
while(b){
if(b & 1) res *= a;
a *= a;
b >>= 1;
}
return res;
}
int solve(int x,int y){
int ans = 0;
ans += f_pow(3,4)*(mat[x][y] - '0');
ans += f_pow(3,3)*(mat[x-1][y] - '0');
ans += f_pow(3,2)*(mat[x+1][y] - '0');
ans += f_pow(3,1)*(mat[x][y-1] - '0');
ans += mat[x][y+1] - '0';
return ans;
}
int f(char c){
if(c == 'U') return 0;
if(c == 'D') return 1;
if(c == 'L') return 2;
if(c == 'R') return 3;
if(c == 'I') return 4;
if(c == 'P') return 5;
return 0;
}
int ff(int x,int y) {
return (x-1)*m+y;
}
bool mov(char c,int &ans,int &x,int &y, int& pre){
int tx = x,ty = y;
if(vis[ff(x,y)] == pre) return false;
vis[ff(x,y)] = pre;
if(c == 'U'){
if(mat[x-1][y] != '1' && x > 1 && mat[x-1][y] != '1')
x--;
}
if(c == 'D'){
if(mat[x+1][y]!='1' && x < n && mat[x+1][y] != '1')
x++;
}
if(c == 'R'){
if(mat[x][y+1] != '1' && y < m && mat[x][y+1] != '1')
y++;
}
if(c == 'L'){
if(mat[x][y-1]!='1' && y > 1 && mat[x][y-1] != '1')
y--;
}
if(c == 'P'){
if(mat[x][y] == '2'){
mat[x][y] = '0';
ans++;
pre = ff(x,y);
}
}
return true;
}
int main(){
cin >> t;
int x,y;
while(t--){
memset(vis,0,sizeof(vis));
scanf("%d%d",&n,&m);
scanf("%d%d%lld",&x,&y,&k);
scanf("%s",s);
int pre = -2;
for(int i = 1; i <= n; i++)
scanf("%s",mat[i] + 1);
int ans = 0;
while(k--){
int p = solve(x,y);
char c = s[p];
if(!mov(c,ans,x,y,pre))
break;
}
printf("%d\n",ans);
}
return 0;
}