P2060 [HNOI2006]马步距离

P2060 [HNOI2006]马步距离

数据到百万级别,明显爆搜不行,剪枝也没法剪。先打表。发现小数据内步数比较受位置关系影响,但数据一大就不影响了。大概搜了一个20*20的表把赋值语句打出来。判断时贪心,看两点间位置差,根据x差或者y差的大小比较来采取两种不同跳法,直到在小范围内再直接借助打的表加以输出。注意起点和目标的位置的及时调整(依据对称性,见line49),方便跳动。

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define dbg(x) cerr<<#x<<" = "<<x<<endl
 7 #define ddbg(x,y) cerr<<#x<<" = "<<x<<"   "<<#y<<" = "<<y<<endl
 8 using namespace std;
 9 typedef long long ll;
10 template<typename T>inline char MIN(T&A,T B){return A>B?A=B,1:0;}
11 template<typename T>inline char MAX(T&A,T B){return A<B?A=B,1:0;}
12 template<typename T>inline T _min(T A,T B){return A<B?A:B;}
13 template<typename T>inline T _max(T A,T B){return A>B?A:B;}
14 template<typename T>inline T read(T&x){
15     x=0;int f=0;char c;while(!isdigit(c=getchar()))if(c=='-')f=1;
16     while(isdigit(c))x=x*10+(c&15),c=getchar();return f?x=-x:x;
17 }
18 const int N=21;
19 int step[N][N]={{0,3,2,3,2,3,4,5,4,5,6,7,6,7,8,9,8,9,10,11,10},
20                 {3,2,1,2,3,4,3,4,5,6,5,6,7,8,7,8,9,10,9,10,11},
21                 {2,1,4,3,2,3,4,5,4,5,6,7,6,7,8,9,8,9,10,11,10},
22                 {3,2,3,2,3,4,3,4,5,6,5,6,7,8,7,8,9,10,9,10,11},
23                 {2,3,2,3,4,3,4,5,4,5,6,7,6,7,8,9,8,9,10,11,10},
24                 {3,4,3,4,3,4,5,4,5,6,5,6,7,8,7,8,9,10,9,10,11},
25                 {4,3,4,3,4,5,4,5,6,5,6,7,6,7,8,9,8,9,10,11,10},
26                 {5,4,5,4,5,4,5,6,5,6,7,6,7,8,7,8,9,10,9,10,11},
27                 {4,5,4,5,4,5,6,5,6,7,6,7,8,7,8,9,8,9,10,11,10},
28                 {5,6,5,6,5,6,5,6,7,6,7,8,7,8,9,8,9,10,9,10,11},
29                 {6,5,6,5,6,5,6,7,6,7,8,7,8,9,8,9,10,9,10,11,10},
30                 {7,6,7,6,7,6,7,6,7,8,7,8,9,8,9,10,9,10,11,10,11},
31                 {6,7,6,7,6,7,6,7,8,7,8,9,8,9,10,9,10,11,10,11,12},
32                 {7,8,7,8,7,8,7,8,7,8,9,8,9,10,9,10,11,10,11,12,11},
33                 {8,7,8,7,8,7,8,7,8,9,8,9,10,9,10,11,10,11,12,11,12},
34                 {9,8,9,8,9,8,9,8,9,8,9,10,9,10,11,10,11,12,11,12,13},
35                 {8,9,8,9,8,9,8,9,8,9,10,9,10,11,10,11,12,11,12,13,12},
36                 {9,10,9,10,9,10,9,10,9,10,9,10,11,10,11,12,11,12,13,12,13},
37                 {10,9,10,9,10,9,10,9,10,9,10,11,10,11,12,11,12,13,12,13,14},
38                 {11,10,11,10,11,10,11,10,11,10,11,10,11,12,11,12,13,12,13,14,13},
39                 {10,11,10,11,10,11,10,11,10,11,10,11,12,11,12,13,12,13,14,13,14}};
40 inline void swap(int&x,int&y){x^=y^=x^=y;}
41 
42 int main(){//freopen("test.in","r",stdin);freopen("test.out","w",stdout);
43     int sx,sy,tx,ty,ans=0;
44     read(sx),read(sy),read(tx),read(ty);
45     if(sx>tx)swap(sx,tx);if(sy>ty)swap(sy,ty);
46     while(tx-sx>=N||ty-sy>=N){//ddbg(sx,sy);
47         if(ty-sy<tx-sx)sx+=2,++sy;
48         else ++sx,sy+=2;++ans;
49         if(sx>tx)swap(sx,tx);if(sy>ty)swap(sy,ty);
50     }
51     return printf("%d",ans+step[tx-sx][ty-sy]),0;
52 }
原文地址:https://www.cnblogs.com/saigyouji-yuyuko/p/10561624.html