CF1023B题解

CF1023B题解

题意

题目的意思浅显易懂:就是有 n 个物品,第 i 件物品价值为 i,问只取其中两个物品,价值能打到 k 的方案数有几个。

思路

首先先看数据范围,1n,k1014,本蒟蒻的暴力梦破裂了,只好用用小学学的数学。

我们知道:若 x+y=z,则 (xs)+(y+s)=zs 可以为任意实数,而本题视为非负整数)。

于是:

  1. k0(mod2),则答案就为 min(k÷21,nk÷2)
  2. k1(mod1),则答案就为 min(k÷2,nk÷2)
  3. 2×n1<k,则无解,输出 0

下面就来解释一下上面的分类讨论:

  1. 为啥要用 min 函数?

答:因为 k 可能是奇数,我们取了中间的两个数,一共有 1k÷21k÷2k,要选出可以配对的数量就是两组数中小的那一组的数量。

  1. 为啥若 2×n1<k,就无解呢?

答:因为每件物品是唯一的,也就是说只能取一次。所以最大的价值就是 2×n1,要是 k 比这个价值还要大的话,绝对无解。

总结

  1. 要开 long long,不开 long long 见祖宗。
  2. 要特判。
  3. 要一点点的小学数学基础。
  4. 需要取小(min 函数)。

代码

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
long long n,k;
int main(){
	scanf("%lld %lld",&n,&k);
	if(2*n-1<k) printf("0");//无解的情况
	//为啥无解呢?
	//因为每件物品是唯一的,也就是说只能取一次。
	//所以最大的价值就是2*n-1,要是k比这个价值还要大的话,绝对无解。
	else if(k%2==0) printf("%lld",min(k/2-1,n-k/2));
	//一定要取小的!
	//因为k可能是奇数,我们取了中间的两个数,一共有1~k/2-1配k/2~k,要选出可以配对的数量就是两组数中小的那一组的数量。
	else printf("%lld",min(k/2,n-k/2));
	//与上面同理。
	return 0;
} 
posted @   naroto2022  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
花开如火,也如寂寞。