原题地址:http://codeforces.com/contest/374/problem/A
好久没写题目总结了,最近状态十分不好,无论是写程序还是写作业还是精神面貌……NOIP挂了之后总觉得缺乏动力精神难以集中……CF做的也是一塌糊涂,各种pretest passed + fail system test,该拿下的总是拿不下,都掉成Specialist了,也不知是什么原因,一点点尽力调整吧这是道水题,本来Div2的第一题就没什么好总结的,但是这道题为整场比赛创造了无数Hack得分(不得不吐槽这场比赛整个就是一逗比……),而且最后AC的人数很少,觉得有必要把没想清楚的地方捋一下,然后抽时间把之前几场的题A掉然后把总结写出来吧
题目大意:有一个n*m的方格,位于(i,j)位置上,每次能同时向上下方向移动a并且向左右方向移动b(必须同时向两个方向移动),求到达任意一个角上所需要的最小移动次数((1,1),(1,m),(n,1),(n,m)中的任意一个),当然,任何时候不可以移动到方格外面
题目分析:非常显然的,我们首先需要判断是否有解。通过分析,我们发现当出现以下情况时,我们才可能得到解。
(1)当初始位置在某个角上时(直接输出0)
(2)初始位置不在角上时,必须与某一个角的垂直距离为k*a,水平距离为t*b(k, t为正整数),且t与k奇偶性相同(原因很简单,我们必须移动max(k, t)次,这个值显然可能会比k和t中的某一个大,那样我们必须在某一方向上先左移再右移(或者先上后下),这个过程需要进行max(k, t) - min(k, t)次,每次操作必须包含两次移动,所以它们奇偶性应该相同)。
特别需要注意的是,我们必须在每个方向都可移动(即走一步之后不会走出棋盘)
然后直接把上面的汉字翻译成代码就可以了
1 //date 20131218 2 #include <cstdio> 3 #include <cstring> 4 5 const int INF = 99999999; 6 7 inline int min(int a, int b){return a < b ? a : b;} 8 inline int max(int a, int b){return a > b ? a : b;} 9 10 int n, m, x, y, a, b; 11 12 int main() 13 { 14 //freopen("a.in", "r", stdin); 15 16 scanf("%d%d%d%d%d%d", &n, &m, &x, &y, &a, &b); 17 18 if((((x - 1) % a != 0) && ((n - x) % a != 0)) || (((y - 1) % b != 0) && ((m - y) % b != 0))) 19 { 20 printf("Poor Inna and pony!\n"); 21 return 0; 22 } 23 24 if(((x == 1) || (x == n)) && ((y == 1) || (y == m))) 25 { 26 printf("0\n"); 27 return 0; 28 } 29 30 int ans = INF; 31 32 if( (((x + a <= n) || (x - a > 0)) && ((y + b <= m) || (y - b > 0))) && (((x - 1) % a == 0) && ((y - 1) % b == 0)) && ((((x - 1) / a) & 1) == (((y - 1) / b) & 1))) 33 ans = min(ans, max((x - 1) / a, (y - 1) / b)); 34 35 if( (((x + a <= n) || (x - a > 0)) && ((y + b <= m) || (y - b > 0))) && (((x - 1) % a == 0) && ((m - y) % b == 0)) && ((((x - 1) / a) & 1) == (((m - y) / b) & 1))) 36 ans = min(ans, max((x - 1) / a, (m - y) / b)); 37 38 if( (((x + a <= n) || (x - a > 0)) && ((y + b <= m) || (y - b > 0))) && (((n - x) % a == 0) && ((y - 1) % b == 0)) && ((((n - x) / a) & 1) == (((y - 1) / b) & 1))) 39 ans = min(ans, max((n - x) / a, (y - 1) / b)); 40 41 if( (((x + a <= n) || (x - a > 0)) && ((y + b <= m) || (y - b > 0))) && (((n - x) % a == 0) && ((m - y) % b == 0)) && ((((n - x) / a) & 1) == (((m - y) / b) & 1))) 42 ans = min(ans, max((n - x) / a, (m - y) / b)); 43 44 if(ans == INF)printf("Poor Inna and pony!\n"); 45 else printf("%d\n", ans); 46 47 return 0; 48 }
收获:还是不仅读题要细致,考虑解决问题时应该尽量各个方面都考虑到,写完代码仔细寻找BUG然后DEBUG,在高质量和熟练度的基础上再追求速度,不能一味求快,更要求稳。最近没少犯这样的错误。