https://www.luogu.org/problemnew/show/P1518
思路一:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll ,ll > P;
#define INF 0xf3f3f3f
const int Max=10000+10;
int dx[4]= {-1,0,1,0};
int dy[4]= {0,1,0,-1};
int c[11][11][4],f[11][11][4];
char m[11][11];
bool ok(int x,int y) {
return x>0&&x<=10&&y>0&&y<=10;
}
int gcd(int x,int y) {
return y?gcd(y,x%y):x;
}
void exgcd(int a,int b,int &x,int &y) {
if(!b) {
x=1;
y=0;
return;
}
exgcd(b,a%b,y,x);
y-=a/b*x;
return;
}
int main() {
int fx,fy,cx,cy;
memset(c,-1,sizeof c);
memset(f,-1,sizeof f);
for(int i=1; i<=10; i++)
for(int j=1; j<=10; j++) {
cin>>m[i][j];
if(m[i][j]=='C') {
cx=i;
cy=j;
}
if(m[i][j]=='F') {
fx=i;
fy=j;
}
}
int t=0;
f[fx][fy][0]=0,c[cx][cy][0]=0;
int tx,ty,nowc=0,nowf=0;
while(1) {
tx=fx+dx[nowf];
ty=fy+dy[nowf];
if(ok(tx,ty)) {
if(m[tx][ty]=='*')
nowf=(nowf+1)%4;
else
fx=tx,fy=ty;
} else
nowf=(nowf+1)%4;
if(f[fx][fy][nowf]==-1)
f[fx][fy][nowf]=++t;
else
break;
}
int ftime=t+1;
t=0;
while(1) {
tx=cx+dx[nowc];
ty=cy+dy[nowc];
if(ok(tx,ty)) {
if(m[tx][ty]=='*')
nowc=(nowc+1)%4;
else
cx=tx,cy=ty;
} else
nowc=(nowc+1)%4;
if(c[cx][cy][nowc]==-1)
c[cx][cy][nowc]=++t;
else
break;
}
int ctime=t+1;
int ans=INF;
for(int i=1; i<=10; i++)
for(int j=1; j<=10; j++)
for(int k=0; k<4; k++)
for(int l=0; l<4; l++) {
if(f[i][j][k]!=-1&&c[i][j][l]!=-1)
{
if(f[i][j][k]<=f[fx][fy][nowf]&&c[cx][cy][nowc]>=c[i][j][l]) {
if(f[i][j][k]==c[i][j][l])
ans=min(ans,f[i][j][k]);
continue;
}
if(f[i][j][k]<=f[fx][fy][nowf]) {
if(f[i][j][k]>=c[i][j][l]) {
if((f[i][j][k]-c[i][j][l])%(ctime-c[cx][cy][nowc])==0)
ans=min(ans,f[i][j][k]);
}
continue;
}
if(c[i][j][l]<=c[cx][cy][nowc]) {
if(c[i][j][l]>=f[i][j][k]) {
if((c[i][j][l]-f[i][j][k])%(ftime-f[fx][fy][nowf])==0)
ans=min(ans,c[i][j][l]);
}
continue;
}
int xtim=ctime-c[cx][cy][nowc],ytim=ftime-f[fx][fy][nowf];
int ch,gd=gcd(xtim,ytim);
if(f[i][j][k]>c[i][j][l]) {
if((f[i][j][k]-c[i][j][l])%gd!=0)
continue;
ch=(f[i][j][k]-c[i][j][l])/gd;
} else {
if((c[i][j][l]-f[i][j][k])%gd!=0)
continue;
ch=(c[i][j][l]-f[i][j][k])/gd;
}
int x,y;
exgcd(xtim,ytim,x,y);
ans=min(ans,x*ch*xtim+f[i][j][k]);
}
}
if(ans==INF)
printf("0\n");
else
printf("%d\n",ans);
return 0;
}
/*
...*.....*
**.......*
.....*..*.
*.*.......
.........*
F.....*.*.
**.*C....*
.......**.
.....*....
....*.*...
146
*/
思路二:
牛跟人一起走,遇到障碍物就转向,同时标记一下每个状态,若形成环则不会相遇,否则输出相遇是的时间
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll ,ll > P;
#define INF 0xf3f3f3f
const int Max=10000+10;
int dx[4]= {-1,0,1,0};
int dy[4]= {0,1,0,-1};
bool m[21][21],vis[21][21][4][21][21][4];
int fx,fy,cx,cy,ft,ct;
void dfs(int step) {
if(fx==cx&&fy==cy) {
printf("%d\n",step);
return ;
}
if(vis[fx][fy][ft][cx][cy][ct]) {
printf("0\n");
return ;
}
vis[fx][fy][ft][cx][cy][ct]=1;
int tx=fx+dx[ft],ty=fy+dy[ft];
if(!m[tx][ty])
fx=tx,fy=ty;
else
ft=(ft+1)%4;
tx=cx+dx[ct],ty=cy+dy[ct];
if(!m[tx][ty])
cx=tx,cy=ty;
else
ct=(ct+1)%4;
dfs(step+1);
}
int main() {
memset(m,0,sizeof m);//0 可以走 1有障碍
memset(vis,0,sizeof vis);//1 标记
char c;
for(int i=0;i<=11;i++)
m[0][i]=1,m[11][i]=1,m[i][0]=1,m[i][11]=1;
for(int i=1; i<=10; i++)
for(int j=1; j<=10; j++) {
cin>>c;
if(c=='C')
cx=i,cy=j;
if(c=='F')
fx=i,fy=j;
if(c=='*')
m[i][j]=1;
}
ft=0,ct=0;
dfs(0);
return 0;
}