kuangbin 数学训练一 Fibsieve`s Fantabulous Birthday
题目链接:传送门#include<iostream>#include<cstdio>#include<cstring>#include<algorithm>#include<cmath>#define ll long longusing namespace std;ll t, num, x, y, k;int main() {scanf(
·
题目链接:
传送门
#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则要转向。
更多推荐
所有评论(0)