#include
using namespace std;
int main()
{
int n, m;
cin >> n >> m;
int x = 1;
int y = 1;
int dx = 1;
int dy = 1;
int cnt = 0;
while (cnt != 2)
{
cnt = 0;
x = x + dx;
y = y + dy;
if (x == 1 || x == n)
{
++cnt;
dx = -dx;
}
if (y == 1 || y == m)
{
++cnt;
dy = -dy;
}
}
cout << x << " " << y << endl;
return 0;
}
输入 1:4 3
输出 1:_________
输入 2:2017 1014
输出 2:_________
1.我们称一次
cnt = 0;
x = x + dx;
y = y + dy;
if (x == 1 || x == n)
{
++cnt;
dx = -dx;
}
if (y == 1 || y == m)
{
++cnt;
dy = -dy;
}
为一步。
2.我们称 x = = 1 ∣ ∣ x = = n ∣ ∣ y = = 1 ∣ ∣ y = = m x==1||x==n||y==1||y==m x==1∣∣x==n∣∣y==1∣∣y==m为到边缘。
可以发现每一步 ( x + y ) (x+y) (x+y)都有三种情况的变化:+2,-2,不变。所以每一步 ( x + y ) (x+y) (x+y)奇偶性不变。而最开始1+1是偶数,所以最后 ( x + y ) (x+y) (x+y)也是偶数。
显然最后不会是n=1且m=1,因为在这之前程序就会结束。
考虑n,m的奇偶性
第一种情况:两个都是偶数 。则 ( 1 + n ) (1+n) (1+n), ( 1 + m ) (1+m) (1+m)都是奇数。最后x=n,y=m。
第二种情况:n是偶数,m是奇数。则 ( 1 + n ) (1+n) (1+n), ( n + m ) (n+m) (n+m)都是奇数,最后x=1,y=m。
第三种情况:n是奇数,m是偶数。与第二种情况类似。最后x=n,y=1。
那么问题来了,当n和m都是奇数的时候答案是什么呢?
因为x,y奇偶性相同,m每次到边缘x,y都是奇数。所以从某一次到边缘到下一次到边缘必经过偶数步。又每一步 ( x + y ) (x+y) (x+y)变化偶数,所以 ( x + y ) (x+y) (x+y)除以4的余数始终不变,为1+1=2。
此时又分几种情况:
第一种情况:n=4p+3,m=4q+3。则 ( n + 1 ) (n+1) (n+1), ( m + 1 ) (m+1) (m+1)都是除以4余0的数。最后x=n,y=m。
第二种情况:n=4p+1,m=4q+3。则 ( n + m ) (n+m) (n+m), ( m + 1 ) (m+1) (m+1)都是除以4余0的数。最后x=n,y=1。
第三种情况:n=4p+3,m=4q+1。则 ( n + m ) (n+m) (n+m), ( n + 1 ) (n+1) (n+1)都是除以4余0的数。最后x=1,y=m。
那么问题来了,当n和m都是除以4余1的数的时候的答案是什么呢?
因为因为每次到边缘必有x=4u+1,y=4v+1。所以从某一次到边缘到下一次到边缘必经过4的倍数步。又每一步 ( x + y ) (x+y) (x+y)变化偶数,所以 ( x + y ) (x+y) (x+y)除以8的余数始终不变,为2。
像之前那样,再分4种情况讨论。。。
这种算法在最坏情况下时间复杂度是 O ( l o g n ) O(logn) O(logn),期望时间复杂度为O(1),非常适合考场上笔算(毕竟这是初赛题,不过这题数据太水,是 O ( 1 ) O(1) O(1)的)
因为这是初赛题,我就不在此次粘O(logn)的程序了。