LOJ1008 Fibsieve's Fantabulous Birthday 数学

题面

https://vjudge.net/problem/LightOJ-1008

分析

简单的数学题。

首先能推出一个规律:行数为奇数/偶数时,横纵坐标的变化顺序是一致的,比如行数为奇数时,纵坐标的取值是[1],[5 6 7],[17 18 19 20 21]...,横坐标的取值是[1],[9 8 7],[25 24 23 22 21]...。

剩下的部分一个个考虑:

①怎么判断数x在第几行:

x在第t行,第t1行表示为t2行。

容易发现,边长为t的矩阵的最大值为t2。故边长为t矩阵的最外层的数范围为[t22+1,t2](如t=5时,最外层就是[17,25])。

那么x一定满足xt,即:

t=(取上整)sqrt(x),t2=(取下整)sqrt(x)

②怎么判断数x在右侧还是上侧:

很显然,x只需要与(t,t)的对角线元素相比即可。

设对角线上坐标为(t,t)的值为w。容易发现w的差分数列是个首项为2p=2的等比数列。

易推出w(t)=t(t1)+1|t>2

显然,当t为奇数时:

  • x<w(t),则x=t,y=s2(t22+1)+1=st22

  • x=w(t),则x=t,y=t

  • x>w(t),则x=t2s+1,y=t

t为偶数时:

  • x<w(t),则x=st22,y=t

  • x=w(t),则x=t,y=t

  • x>w(t),则x=t,y=t2s+1

可以发现,奇偶行的横纵坐标其实只是颠倒了过来,完全不用独立分析。

Code

void solve(int T, LL s) {
    if (s == 1) {
        printf("Case %d: 1 1\n", T);
        return;
    }
    LL x = 0, y = 0;
    LL t = (LL) ceil(sqrt(s)), t2 = (LL) floor(sqrt(s));
    LL num = t * (t - 1) + 1;
    if (t & 1LL) {
        if (s < num) x = t, y = s - t2 * t2 * 1LL;
        else if (s == num) x = t, y = t;
        else x = t * t * 1LL - s + 1, y = t;
    } else {
        if (s < num) x = s - t2 * t2 * 1LL, y = t;
        else if (s == num) x = t, y = t;
        else x = t, y = t * t * 1LL - s + 1;
    }
    printf("Case %d: %lld %lld\n", T, x, y);
}
posted @   SxtoxA  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
12 13
点击右上角即可分享
微信分享提示