CF1023B Pair of Toys 题解

简化题意

求 1 到 nn 中取两个数,问有几种方案。

做法

Unaccepted\color{red}{Unaccepted}

直接暴力,枚举两个数(因为题目中说了选 a b 和选 b a 都是相同的,所以可以直接枚举所有 a<ba < ba b)。

1
2
3
4
5
6
7
8
9
10
11
12
#include<bits/stdc++.h>
using namespace std;
long long n,k;
long long cnt;
int main(){
ios_base::sync_with_stdio(false);
cin>>n>>k;
for(int i=1;i<=n;++i) for(int j=i+1;j<=n;++j) if(i+j==k) ++cnt;
cout<<cnt<<endl;
return 0;
}
//TLE on #4

正解

刚刚上面的做法太暴力了,因为它 Θ(n2)\Theta(n^2) 的时间复杂度以及 1n,k10141 \le n,k \le 10^{14} 的数据范围 TLE 掉了。

现在我们先进行一些数学的证明:

a+b=a+b\because a + b = a + b

a+b+cc=a+b\therefore a + b + c - c = a + b

a+c+bc=a+b\therefore a + c + b - c = a + b

(a+c)+(bc)=a+b\therefore ( a + c ) + ( b - c ) = a + b

所以我们知道当 a+b=ka+b=k(a+1)+(b1)=k( a + 1 ) + ( b - 1 ) = k

而且第一组物品就是 0 k - 1

但是如果 kk 大于 n×21n \times 2 - 1 就无解了。

因为最大的一组是 n n-1,所以最大的一组和就是 n+n1n + n - 1 ,kk 大于它就无解了。

于是判断一下 kk 的奇偶性再在第一个数和第二个数的个数之间取 min\min 就行了。

上代码:

1
2
3
4
5
6
7
8
9
10
11
#include<bits/stdc++.h>
using namespace std;
long long n,k;
int main(){
ios_base::sync_with_stdio(false);
cin>>n>>k;
if(n*2-1<k) cout<<0;
else if(!(k&1)) cout<<min(k/2-1,n-k/2);
else cout<<min(k/2,n-k/2);
return 0;
}

CF1023B Pair of Toys 题解
https://www.lzj-blog.top/2023/11/21/CF1023B Pair of Toys 题解/
作者
lzj
发布于
2023年11月21日
许可协议