专栏文章

题解:P10090 [ROIR 2022 Day 2] 幼儿园的新年

P10090题解参与者 4已保存评论 5

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
5 条
当前快照
1 份
快照标识符
@mir340ix
此快照首次捕获于
2025/12/04 14:58
3 个月前
此快照最后确认于
2025/12/04 14:58
3 个月前
查看原文

题目传送门

写一篇和其他题解不一样的解题思路(个人感觉更好理解)。
我们用一个二维矩阵来观察 x,y 之和的关系,如下图,可以发现矩阵对角线上的 x,y 之和相等,所以我们就可以找到满足条件的 x+yn 的倍数的所有情况。
举例:2 4 6
如下图 :
我们要求的是标红的矩阵里的所有 2 的倍数的数字个数,即红色矩阵里画斜线数字的数量,蓝色斜线是全部在要求的矩阵里的,红色斜线是部分在要求的矩阵里的,我们可以先求有颜色的大三角形里 2 的倍数的数字的个数,再减去两个标黄色的小三角形里 2 的倍数的数字的个数,可以看出,每个三角形里的不同的数字的个数组成了等差数列,所以我们可以直接用等差数列来求和。
代码如下:
CPP
#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll t;
int main(){
	scanf("%lld",&t);
	while(t--){
		ll n,a,b;
		ll ans=0;
		scanf("%lld%lld%lld",&n,&a,&b);
		ll minn=min(a,b);
		ll maxn=max(a,b);
		ll end=(minn/n+1)*n;//短的那一部分超出矩阵部分的第一个n的倍数 
		ll end2=(maxn/n+1)*n;//长的那一部分超出矩阵部分的第一个n的倍数 
		ll x=(a+b);//要求的这个矩阵里最大的值 
		if(n<=x)ans=((n+1)+(n+1+(x-n)/n*n))*((x-n)/n+1)/2;//先求出所有的数量 ,如果n本来就比矩阵里最大的数大,那么答案为0 
		if(end<=x){//需要判断 
			ans-=(((end-minn)+(end-minn+(x-end)/n*n))*((x-end)/n+1))/2;
		}//分别减去多余的部分 
		if(end2<=x){//需要判断 
			ans-=(((end2-maxn)+(end2-maxn+(x-end2)/n*n))*((x-end2)/n+1))/2;
		}//分别减去多余的部分 
		printf("%lld\n",ans);
	}
	return 0;
}

评论

5 条评论,欢迎与作者交流。

正在加载评论...