UVa 10161 - Ant on a Chessboard

本文详细解析了UVa10161-AntonaChessboard题目,通过观察矩阵特点找到了两种不同的解题方法。一种是利用副对角线值与输入之间的关系;另一种则是通过坐标轴上的位置关系来解决问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

传送门UVa 10161 - Ant on a Chessboard

一样, 看了二十来分钟没有思路.

刚看解题报告的时候还看不懂, 看了好久, 又观察了一下那个矩阵, 终于摸索出了门道来.

这题的要点在于要发现那条 "副对角线"  的值和输入的关系. 副对角线的值等于 n(n - 1) + 1, 然后把输入开根号就可以得到行或者列 (这里我想了很久还是想不懂原理...) , 接着根据他们的关系得出结果.看完解题报告我只想说三个字:

这TM谁想得出来啊!!!"

具体请看代码 I

PS: 我觉得我要在数学专题上往死里跪了. 我已经做好做一题看一次解题报告的准备了

----------------------------------------我是华丽的分割线-----------------------------------------

4.15日补充


今天上英语课又把这个题拿出来想, 终于让我找出了一些规律, 虽然没有方便多少, 但是对我来说是好理解多了, 至少不用去看那条"副对角线"的值(ˉ▽ ̄~)

观察一下那个矩阵, 就像圆一样,


n的平方要么在y轴上, 要么在x轴上 (请原谅我简陋地拿坐标轴过来说), 而且根据n的奇偶, 只是递增的方向不一样, 并且n的平方最大.

哎...我又描述不出来了...大家意会一下吧.. 就是可以拿n平方和step的差来算.详情见代码 II

PS:想这道题的时候老师正好在提问听力, 然后我竟然被叫起来了.然后......TAT

 

/************************************代码 I***************************************/

#include <cstdio>
#include <cmath>

using namespace std;

int main()
{
    //freopen("input.txt", "r", stdin);
    int colomn;
    int step;
    int row;
    int value;
    while (scanf("%d", &step) == 1 && step)
    {
        int c = (int)ceil(sqrt(step));
        //c可能是行或者列.要和那条"对角线"上的值对比才能得出.
        value = c * (c - 1) + 1;
        if (c & 1)  //如果c是奇数.
        {
            if (step >= value)     //如果step大于那个值, 则c就是行.
            {
                row = c;
                colomn = c - (step - value);
            }
            else        //c是列.
            {
                    colomn = c;
                    row = c - (value - step);

            }
        }
        else        //和上面相反
        {
            if (step >= value)      //此时c是列.
            {
                colomn = c;
                row = c - (step - value);
            }
            else    //c是行
            {
                row = c;
                colomn = c - (value - step);
            }
        }
        printf("%d %d\n", colomn, row);
    }
    return 0;
}

/***************************************代码 II****************************************/


#include <cstdio>
#include <cstring>
#include <cmath>

using namespace std;

int main()
{
    int step;
    int n, value;
    int colomn, row;
    int differ;
    while (scanf("%d", &step) == 1 && step)
    {
        n = (int)ceil(sqrt(step));
        value = n * n;
        differ = value - step;      //计算出step和value的差.
        if (n & 1)      //如果n是奇数, 观察得, 从右往左数
        {
            if (differ > n - 1) //说明需要"拐弯", 即行数有变化, 此时列数和n相等.
            {
                colomn = n;
                row = n - (differ - (n - 1));      //这个观察一下也很容易得出来.
            }
            else    //此时不需要"拐弯"
            {
                row = n;
                colomn = 1 + differ;    //观察一下...
            }

        }
        else
        {
            if (differ > n - 1)
            {
                colomn = 2 * n - differ - 1;     //就把上面那个式子化简了一下.
                row = n;
            }
            else
            {
                colomn = n;
                row = 1 + differ;
            }
        }
        printf("%d %d\n", colomn, row);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值