#P2186. 第1题-计算积分
          
                        
                                    
                      
        
              - 
          
          
                      1000ms
            
          
                      Tried: 113
            Accepted: 28
            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。