P1336飞翔
背景
鹰最骄傲的就是翱翔,但是鹰们互相都很嫉妒别的鹰比自己飞的快,更嫉妒其他的鹰比自己飞行的有技巧。于是,他们决定举办一场比赛,比赛的地方将在一个迷宫之中。
描述
这些鹰的起始点被设在一个N*M矩阵的左下角map[1,1]的左下角。终点被设定在矩阵的右上角map[N,M]的右上角,有些map[i,j]是可以从中间穿越的。每一个方格的边长都是100米。如图所示:
没有障碍,也没有死路。这样设计主要是为了高速飞行的鹰们不要发现死路来不及调整而发生意外。潘帕斯雄鹰冒着减RP的危险从比赛承办方戒备森严的基地中偷来了施工的地图。但是问题也随之而来,他必须在比赛开始之前把地图的每一条路都搞清楚,从中找到一条到达终点最近的路。(哈哈,笨鸟不先飞也要拿冠军)但是此鹰是前无古鹰,后无来鹰的吃菜长大的鹰--菜鸟。他自己没有办法得出最短的路径,于是紧急之下找到了学OI的你,希望找到你的帮助。
格式
输入格式
首行为n,m(0<n,m<=1000000),第2行为k(0<k<=1000)表示有多少个特殊的边。以下k行为两个数,i,j表示map[i,j]是可以直接穿越的。
输出格式
仅一行,1,1-->n,m的最短路径的长度,四舍五入保留到整数即可
样例
输入
3 2
3
1 1
3 2
1 2
输出
383
思路
太久了早就忘记了自己看代码吧……
代码
#include<iostream> #include<cmath> #include<iomanip> #include<cstdio> #include<algorithm> using namespace std; int main() { long long i,j,k,a,b,m,n,tmp,s,t,best; double distance; long special[1005][4]; //special[i][0]表示第i条斜边左下角顶点x坐标,special[i][1]表示第i条斜边左下角顶点y坐标 long x,y; {cin>>n>>m; //读入 cin>>k; for (i=1;i<=k;++i) //读入一叠叠的坐标 cin>>special[i][0]>>special[i][1]; } for (i=1;i<=k;++i) //冒泡排序,准则:先x后y升序排列,使需要查找时向左查找 ★现在做的是x升序排序★纵坐标不用排★ { for (j=i+1;j<=k;++j) { if (special[i][0]>special[j][0]) { for (s=0;s<=3;++s) //整个点的所有内容转移,懒得打4遍 {tmp=special[i][s];special[i][s]=special[j][s];special[j][s]=tmp;} } } } for (i=1;i<=k;++i) special[i][2]=0; //初始化special[i,2]值,使自己算一条 for (i=1;i<=k;++i) { for (j=1;j<=i;++j) { if ((special[i][0]>special[j][0])and(special[i][1]>special[j][1])) { if (special[j][2]+1>special[i][2]) special[i][2]=special[j][2]+1; } } } distance=100*m+100*n; best=0; for (i=1;i<=k;++i) {if (special[i][2]>best) best=special[i][2];} best=best+1; distance=distance-200*best+best*sqrt(2)*100; cout<<int(distance+0.5)<<endl; return 0; }