题目链接:
传送门

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;

ll t, num, x, y, k;

int main() {
	scanf("%lld", &t);
	while(t--) {
		scanf("%lld", &num);
		//寻找当前数字所在的区间
		ll m = sqrt(num);
		ll eo = m % 2;
		ll dif = num - m * m;
		//如果当前数是一个最大值
		if(dif == 0) {
			//根据区间的奇偶不同进行判断
			if(eo) {
				printf("Case %lld: %lld %lld\n", ++k, 1, m);
			} else {
				printf("Case %lld: %lld %lld\n", ++k, m, 1);
			}
		//判断其他情况
		} else {
			//判断当前数字在横向区域还是竖向区域
			if(dif <= m + 1) {
				//根据区间的奇偶不同进行判断
				if(eo) {
					printf("Case %lld: %lld %lld\n", ++k, dif, m + 1);
				} else {
					printf("Case %lld: %lld %lld\n", ++k, m + 1, dif);
				}
			} else {
				//根据区间的奇偶不同进行判断
				if(eo) {
					printf("Case %lld: %lld %lld\n", ++k, m + 1, 2 * (m + 1) - dif);
				} else {
					printf("Case %lld: %lld %lld\n", ++k, 2 * (m + 1) - dif, m + 1);
				}
			}
		}
	}
}

这道题属于思维题,我们可以把这个序列按图分类:
在这里插入图片描述
我们会发现每一组中的最大值即为当前组数的平方,最小值即为上一组最大值 + 1.
同时根据奇偶性不同,其最大值与最小值也会不一样。所以我们每次寻找区间时,我们每次找数字的时候的起点可能都有所不同(因为其最小值的位置不一)
同时寻找当前值在区间哪一个位置时要分两个部分来讨论,一个是横向的区域,一个是竖向区域,我们只要判断当前值与最小值 - 1的差值即可,如果dif > m + 1则要转向。

Logo

永洪科技,致力于打造全球领先的数据技术厂商,具备从数据应用方案咨询、BI、AIGC智能分析、数字孪生、数据资产、数据治理、数据实施的端到端大数据价值服务能力。

更多推荐