【洛谷】P2689 东南西北(dfs|贪心)
P2689 东南西北
题目描述
给出起点和终点的坐标及接下来T个时刻的风向(东南西北),每次可以选择顺风偏移1个单位或者停在原地。求到达终点的最少时间。
如果无法偏移至终点,输出“-1”。
输入输出格式
输入格式:
第一行两个正整数x1,y1,表示小明所在位置。
第二行两个正整数x2,y2,表示小明想去的位置。
第三行一个整数T,表示T个时刻。
第四至第N+3行,每行一个字符,表示风向,即东南西北的英文单词的首字母。
输出格式:
最少走多少步。
输入输出样例
说明
样例1:向东走一步,向南走一步。
样例2、3:无法到达。
1<=T<=50
东:East
南:South
西:West
北:North
【题解】【首先要搞清楚一点,这里所说的风向是吹向哪个方向的风而不是我们通常意义上的东西南北风,即N代表当前可以顺风向北走一个单位。还有一点要注意的是这里的坐标的增减是按照平面直角坐标系的原则的,即向北纵坐标增大,向东横坐标增大】
【dfs每一时刻都有顺风行走和不动两种状态,然后 dfs下一时刻的行走可能。边界:到达目的地或提供的时刻全部用完】
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 char s[55]; 8 int s0,t0,s1,t1,n,num; 9 void dfs(int x,int y,int f,int t){ 10 if(x==s1&&y==t1) {num=min(t,num); return;} 11 if(f>n) return; 12 if(s[f]=='E') dfs(x+1,y,f+1,t+1); 13 if(s[f]=='W') dfs(x-1,y,f+1,t+1); 14 if(s[f]=='S') dfs(x,y-1,f+1,t+1); 15 if(s[f]=='N') dfs(x,y+1,f+1,t+1); 16 dfs(x,y,f+1,t); 17 return; 18 } 19 int main(){ 20 int i; 21 scanf("%d%d%d%d%d\n",&s0,&t0,&s1,&t1,&n); 22 for(i=1;i<=n;++i) scanf("%c\n",&s[i]); 23 num=1000000000; 24 dfs(s0,t0,1,0); 25 if(num==1000000000) printf("-1\n"); 26 else printf("%d\n",num); 27 return 0; 28 }
【贪心,我们知道,从一个点到另一个点的图上最短路就是两点的横坐标差+纵坐标差,与路线无关,因此只需判断所给的所有风向是否能满足横坐标和纵坐标的变更需求即可】
#include<cstdio> #include<cstring> #include<iostream> using namespace std; char c; int x0,y0,x1,y1,t,n,e,w,s,ans,p; int main(){ int a,b,i; scanf("%d%d%d%d%d",&x0,&y0,&x1,&y1,&t); for(i=1;i<=t;++i) { cin>>c; if(c=='E') e++; if(c=='N') n++; if(c=='S') s++; if(c=='W') w++; } a=x1-x0; b=y1-y0; if(a>0) if(a<=e) p++; if(a<0) { a=-a; if(a<=w) p++; } if(a==0) p++; if(p) { if(b>0) if(b<=n) p++; if(b<0) { b=-b; if(b<=s) p++; } if(b==0) p++; } if(p==2) printf("%d",a+b); else printf("-1"); return 0; }
既然无能更改,又何必枉自寻烦忧