[HNOI2006]马步距离
这题首先直接bfs可定过不了,因此可以先贪心缩小两个点的距离,直到达到某一个较小的范围(我用的是30),再bfs暴力求解。
首先我们求出这两个点的相对距离x, y,这样就相当于从(x, y) 走到(0, 0)。然后贪心时,x, y哪一个大,就-=2,另一个--。注意的是要一直保持x, y都是正的,所以每次去绝对值,这种做法正确性可以保证,因为根据题中给的图,可以知道他有对称性。
1 #include<cstdio> 2 #include<iostream> 3 #include<algorithm> 4 #include<cmath> 5 #include<cstring> 6 #include<cstdlib> 7 #include<stack> 8 #include<queue> 9 #include<vector> 10 #include<cctype> 11 using namespace std; 12 #define enter puts("") 13 #define space putchar(' ') 14 #define Mem(a) memset(a, 0, sizeof(a)) 15 typedef long long ll; 16 typedef double db; 17 const int INF = 0x3f3f3f3f; 18 const db eps = 1e-8; 19 const int maxn = 105; 20 inline ll read() 21 { 22 ll ans = 0; 23 char ch = getchar(), last = ' '; 24 while(!isdigit(ch)) {last = ch; ch = getchar();} 25 while(isdigit(ch)) {ans = ans * 10 + ch - '0'; ch = getchar();} 26 if(last == '-') ans = -ans; 27 return ans; 28 } 29 inline void write(ll x) 30 { 31 if(x < 0) putchar('-'), x = -x; 32 if(x >= 10) write(x / 10); 33 putchar(x % 10 + '0'); 34 } 35 36 ll cnt = 0; 37 38 int dx[10] = {0, -2, -1, 1, 2, 2, 1, -1, -2}, dy[10] = {0, 1, 2, 2, 1, -1, -2, -2, -1}; 39 bool vis[maxn][maxn]; 40 struct Node 41 { 42 int x, y, dis; 43 }; 44 int bfs(int x, int y) 45 { 46 queue<Node> q; 47 q.push((Node){x, y, 0}); 48 vis[x][y] = 1; 49 while(!q.empty()) 50 { 51 Node now = q.front(); q.pop(); 52 for(int i = 1; i <= 8; ++i) 53 { 54 int newx = now.x + dx[i], newy = now.y + dy[i]; 55 if(newx == 30 && newy == 30) return now.dis + 1; 56 if(newx >= 0 && newx <= 60 && newy >= 0 && newy <= 60 && !vis[newx][newy]) 57 { 58 vis[newx][newy] = 1; 59 q.push((Node){newx, newy, now.dis + 1}); 60 } 61 } 62 } 63 return 0; 64 } 65 66 int main() 67 { 68 int xp = read(), yp = read(), xs = read(), ys = read(); 69 int x = abs(xp - xs), y = abs(yp - ys); 70 while(x + y > 30) 71 { 72 if(x < y) swap(x, y); 73 x -= 2; y -= 1; 74 cnt++; 75 x = abs(x); y = abs(y); 76 } 77 cnt += bfs(x + 30, y + 30); //防止下标出现负数 78 write(cnt); enter; 79 }