题解 宝可梦
发现它走的路径是一个环,于是就变成了计算环上两点间距离
当然细节有亿点多
Code:
#include <bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define N 500010
#define ll long long
//#define int long long
int n, m, q;
bool **mp;
char s[N], t1[10];
namespace force{
const int dlt[][2]={{1,0},{0,1},{-1,0},{0,-1}};
int calc(int x, int y, int c, int d, int t) {
int tot=1, nxt, nxtx, nxty;
if (x==c && y==d) return 0;
x=x+dlt[t][0], y=y+dlt[t][1];
while (1) {
// cout<<"tot: "<<tot<<' '<<x<<' '<<y<<endl;
if (x==c && y==d) return tot;
++tot;
nxt=((t-1)%4+4)%4;
nxtx=x+dlt[nxt][0], nxty=y+dlt[nxt][1];
if (!mp[nxtx][nxty]) x=nxtx, y=nxty, t=nxt;
else {
nxt=t;
nxtx=x+dlt[nxt][0], nxty=y+dlt[nxt][1];
while (mp[nxtx][nxty]) {
nxt=(nxt+1)%4;
nxtx=x+dlt[nxt][0], nxty=y+dlt[nxt][1];
}
x=nxtx, y=nxty, t=nxt;
}
}
}
void solve() {
for (int i=1,a,b,c,d,dir; i<=q; ++i) {
scanf("%d%d%d%d%s", &a, &b, &c, &d, t1);
if (*t1=='U') dir=2;
else if (*t1=='D') dir=0;
else if (*t1=='L') dir=3;
else dir=1;
printf("%d\n", calc(a, b, c, d, dir));
}
exit(0);
}
}
namespace task1{
int vis[N][4];
const int dlt[][2]={{1,0},{0,1},{-1,0},{0,-1}};
inline int num(int i, int j) {return (i-1)*m+j;}
void solve() {
int x, y, u, t=0, nxtx, nxty, nxt, tot=0;
int sx, sy;
for (int j=1; j<=m; ++j) for (int i=1; i<=n; ++i) if (!mp[i][j]) {sx=x=i, sy=y=j; goto jump;}
jump: ;
memset(vis, -1, sizeof(vis));
// cout<<"xy: "<<x<<' '<<y<<endl;
while (vis[u=num(x, y)][t]==-1 || u!=num(sx, sy)) {
vis[u][t]=tot++;
// printf("vis[%d,%d][%d]=%d\n", x, y, t, tot-1);
nxt=((t-1)%4+4)%4;
nxtx=x+dlt[nxt][0], nxty=y+dlt[nxt][1];
if (!mp[nxtx][nxty]) {
// assert(vis[u][nxt]==-1);
// if (vis[u][nxt]!=-1) cout<<"error: "<<x<<' '<<y<<' '<<nxt<<endl;
if (vis[u][nxt]==-1) {
// vis[u][nxt]=tot-1, printf("vis0[%d,%d][%d]=%d\n", x, y, nxt, tot-1);
}
x=nxtx, y=nxty, t=nxt;
// cout<<"pos1"<<endl;
}
else {
// cout<<"pos2"<<endl;
nxt=t;
nxtx=x+dlt[nxt][0], nxty=y+dlt[nxt][1];
while (mp[nxtx][nxty]) {
// if (nxt!=t && ~vis[u][nxt]) goto jump2;
if (nxt!=t) {
vis[u][nxt]=tot-1;
// printf("vis1[%d,%d][%d]=%d\n", x, y, nxt, tot-1);
}
nxt=(nxt+1)%4;
nxtx=x+dlt[nxt][0], nxty=y+dlt[nxt][1];
}
// cout<<"pos3"<<endl;
if (nxt!=t) {
if (vis[u][nxt]!=-1) {
// cout<<"error: "<<x<<' '<<y<<' '<<nxt<<endl;
break;
}
// if (nxt!=t && ~vis[u][nxt]) goto jump2;
vis[u][nxt]=tot-1;
// printf("vis2[%d,%d][%d]=%d\n", x, y, nxt, tot-1);
}
x=nxtx, y=nxty, t=nxt;
}
jump2: ;
}
--tot;
// cout<<"tot: "<<tot<<endl;
int ans;
for (int i=1,a,b,c,d,dir; i<=q; ++i) {
ans=INF;
scanf("%d%d%d%d%s", &a, &b, &c, &d, t1);
if (a==c&&b==d) {puts("0"); continue;}
if (mp[a][b]||mp[c][d]) {puts("-1"); continue;}
if (*t1=='U') dir=2;
else if (*t1=='D') dir=0;
else if (*t1=='L') dir=3;
else dir=1;
a=a+dlt[dir][0], b=b+dlt[dir][1];
if (mp[a][b]) {puts("-1"); continue;}
if (a==c&&b==d) {puts("1"); continue;}
for (int j=0,u=num(a,b),v=num(c,d); j<4; ++j) {
if (vis[v][j]!=-1) {
// cout<<vis[u][dir]<<' '<<vis[v][j]<<endl;
if (vis[v][j]>vis[u][dir]) ans=min(ans, vis[v][j]-vis[u][dir]);
else ans=min(ans, tot+vis[v][j]-vis[u][dir]);
}
}
printf("%d\n", ans+1);
}
exit(0);
}
}
signed main()
{
freopen("pokemon.in", "r", stdin);
freopen("pokemon.out", "w", stdout);
scanf("%d%d", &n, &m);
mp=new bool*[n+2];
for (int i=0; i<=n+1; ++i) {
mp[i]=new bool[m+2];
for (int j=0; j<=m+1; ++j) mp[i][j]=1;
}
for (int i=1; i<=n; ++i) {
scanf("%s", s+1);
for (int j=1; j<=m; ++j) mp[i][j]=(s[j]=='X');
}
scanf("%d", &q);
if (n<=20 && m<=20 && q<=20) force::solve();
else task1::solve();
return 0;
}