NOIP2017初赛阅读程序写结果第4题题解

这篇博客详细解析了NOIP2017初赛阅读程序写结果第4题,讨论了在不同情况下变量x和y的奇偶性变化,并给出了每种情况的解题思路。通过分析,得出在最坏情况下,该算法的时间复杂度为O(logn),但期望时间复杂度为O(1),适合快速笔算解答。

NOIP2017初赛阅读程序写结果第4题题解

一、题面

#include<iostream>
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==mx==1||x==n||y==1||y==mx==1x==ny==1y==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(logn)O(logn)O(logn),期望时间复杂度为O(1),非常适合考场上笔算(毕竟这是初赛题,不过这题数据太水,是O(1)O(1)O(1)的)

四、标程

因为这是初赛题,我就不在此次粘O(logn)的程序了。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值