#P2186. 第1题-计算积分
-
1000ms
Tried: 119
Accepted: 29
Difficulty: 3
所属公司 :
百度
时间 :2024年10月15日-算法
-
算法标签>数学
第1题-计算积分
思路
对于奇数偶数分开讨论
1.n是奇数的情况如果优先选择奇数可以获得(n+1)/2个积分,偶数则是(n-1)/2个积分,那么我们优先填奇数,如果还有剩余的数则都是减回去的。
2.n是偶数的情况优先奇数优先偶数都是一样的,假设我们优先选择偶数,那么剩余的数-1则是需要减回去的(因为再选择1的话不会导致积分变少)
详细实现看代码
#include <bits/stdc++.h>
using namespace std;
long long n, k, res; // 定义全局变量n、k和res,n表示总数,k表示选择的个数,res表示结果(最多能获得的积分)
int t; // 定义全局变量t,表示测试数据的组数
int main() {
int t; // 测试数据组数
cin >> t; // 输入测试数据的组数
while(t--) { // 循环遍历每一组测试数据
cin >> n >> k; // 输入每组数据中的n和k,n是数的范围,k是要选择的个数
// 如果n是奇数
if(n % 2 == 1) {
// res先计算为(n+1)/2与k中较小的那个数
// 这一步的意思是优先选择前面一半的数,因为选择一个整数i并且i+1没有被选的话,可以得1分
res = min((n+1)/2, k);
// 更新k,扣除已经选中的数量
k -= res;
// 如果还剩下要选择的数量(即k大于0),说明选了后面的数,扣分
if(k > 0) {
res -= k; // 选了后面的数会扣除相应的积分
}
}
// 如果n是偶数
else {
// res先计算为n/2与k中较小的那个数
// 这一步的意思是选择前面的一半数(因为它们更容易得分)
res = min(n/2, k);
// 更新k,扣除已经选中的数量
k -= res;
// 如果k大于0,说明还有剩余需要选择的数,这些会影响积分
if(k > 0) {
res -= k - 1; // 对于n为偶数的情况,剩余的k会扣掉一些积分
}
}
// 输出每组测试数据的结果,即最多能获得的积分
cout << res << '\n';
}
return 0; // 返回0,程序正常结束
}
python
t = int(input()) # 输入测试数据组数
for _ in range(t): # 循环遍历每一组测试数据
n, k = map(int, input().split()) # 输入每组数据中的n和k,n是数的范围,k是要选择的个数
# 如果n是奇数
if n % 2 == 1:
# res先计算为(n+1)//2与k中较小的那个数
res = min((n + 1) // 2, k)
# 更新k,扣除已经选中的数量
k -= res
# 如果还剩下要选择的数量(即k大于0),说明选了后面的数,扣分
if k > 0:
res -= k # 选了后面的数会扣除相应的积分
# 如果n是偶数
else:
# res先计算为n//2与k中较小的那个数
res = min(n // 2, k)
# 更新k,扣除已经选中的数量
k -= res
# 如果k大于0,说明还有剩余需要选择的数,这些会影响积分
if k > 0:
res -= (k - 1) # 对于n为偶数的情况,剩余的k会扣掉一些积分
# 输出每组测试数据的结果,即最多能获得的积分
print(res)
java
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.IOException;
public class Main {
public static void main(String[] args) throws IOException {
// 使用 BufferedReader 进行快速输入
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder(); // 用于快速输出结果
int t = Integer.parseInt(br.readLine()); // 输入测试数据组数
while (t-- > 0) {
// 读取每组数据
String[] input = br.readLine().split(" ");
long n = Long.parseLong(input[0]); // 输入n,n是数的范围
long k = Long.parseLong(input[1]); // 输入k,k是要选择的个数
long res;
// 如果n是奇数
if (n % 2 == 1) {
// res先计算为(n+1)/2与k中较小的那个数
res = Math.min((n + 1) / 2, k);
// 更新k,扣除已经选中的数量
k -= res;
// 如果还剩下要选择的数量(即k大于0),说明选了后面的数,扣分
if (k > 0) {
res -= k; // 选了后面的数会扣除相应的积分
}
}
// 如果n是偶数
else {
// res先计算为n/2与k中较小的那个数
res = Math.min(n / 2, k);
// 更新k,扣除已经选中的数量
k -= res;
// 如果k大于0,说明还有剩余需要选择的数,这些会影响积分
if (k > 0) {
res -= (k - 1); // 对于n为偶数的情况,剩余的k会扣掉一些积分
}
}
// 将结果追加到 StringBuilder 中
sb.append(res).append("\n");
}
// 最终输出所有结果
System.out.print(sb.toString());
}
}
题目内容
整数 1 ~ n ,计算选择 k 个数最多能获得多少积分。
计分规则:初始积分为 0,对于被选取的整数 i ,如果 i+1 没选,则积分加 1 。
输入描述
每个测试文件均包含多组测试数据。
第一行输入一个整数 T(1≤T≤105)代表数据组数,每组测试数据描述如下:
在一行上输入两个整数 n,k(1≤n,k≤1012;k≤n),含义和题面描述一致。
输出描述
对于每一组测试数据,在一行上输出一个整数,代表最多能获得的积分。
样例1
输入
2
1 1
4 2
输出
1
2
说明
第一个样例选择 1,积分为 1 。
第二个样例一种可行方案为 1,3,积分为 2。