题解:学而思编程 排位

【题目来源】

学而思编程:排位

【题目描述】

\(n\) 个人排成了一队,小X就在其中。

他不知道自己的确切排位,但是他能确定的是,排在他前面的人不少于 \(a\) 个,排在他后面的人不超过 \(b\) 个。

请问,对于他的具体排位,一共有多少种可能性?

【输入】

第一行包含整数 \(T\),表示共有 \(T\) 组数据。

每组数据占一行,包含三个整数 \(n,a,b\)

【输出】

每组数据输出一行结果,一个整数,表示小X具体排位的可能数量。

【输入样例】

2
3 1 1
5 2 3

【输出样例】

2
3

【核心思想】

  1. 问题分析:给定 \(n\) 个人排队,小X前面不少于 \(a\) 人,后面不超过 \(b\) 人。求小X排位的可能数量。这是一个区间计数问题,关键在于将"前面不少于 \(a\)"和"后面不超过 \(b\)"转化为小X位置的数学约束,计算合法位置区间的长度。

  2. 算法选择

    • 位置建模:设小X排在第 \(k\) 位(从 \(1\) 开始计数),前面有 \(k-1\) 人,后面有 \(n-k\)
    • 不等式约束:将题意转化为关于 \(k\) 的不等式组,求解合法 \(k\) 的区间范围
  3. 关键步骤

    • 读取输入:读取测试组数 \(T\)
    • 逐组处理(循环 \(T\) 次):
      • 读取 \(n\)(总人数)、\(a\)(前面不少于 \(a\) 人)、\(b\)(后面不超过 \(b\) 人)
      • 建立约束
        • 前面不少于 \(a\) 人:\(k - 1 \ge a \Rightarrow k \ge a + 1\)
        • 后面不超过 \(b\) 人:\(n - k \le b \Rightarrow k \ge n - b\)
        • 位置合法性:\(1 \le k \le n\)
      • 综合约束\(k \ge \max(a + 1, n - b)\)\(k \le n\)
      • 计算合法区间长度
        • \(a + b = n\):合法位置为 \(k \in [a+1, n]\),数量为 \(n - a = b\)
        • \(a + b < n\):合法位置为 \(k \in [n-b, n]\),数量为 \(b + 1\)
        • \(a + b > n\):约束冲突,前面至少 \(a\) 人且后面最多 \(b\) 人,总人数至少 \(a + 1 + 0 = a + 1\),但 \(a + b > n\) 意味着 \(a > n - b\)。合法位置为 \(k \in [a+1, n]\),数量为 \(n - a\)
    • 输出结果:根据上述三种情况输出对应数量
  4. 时间/空间复杂度

    • 时间复杂度:\(O(T)\),每组数据 \(O(1)\) 计算
    • 空间复杂度:\(O(1)\),仅使用常数个变量
  5. 区间约束的核心思想

    • 双约束交集:小X的位置受"前面不少于 \(a\)"和"后面不超过 \(b\)"两个约束共同限制,合法位置是两者的交集
    • 边界情况分析
      • \(a + b = n\):约束恰好饱和,小X位置固定为 \(a+1\)\(n\)\(b\) 个位置
      • \(a + b < n\):约束宽松,存在额外空间,小X可以在 \(n-b\)\(n\)\(b+1\) 个位置
      • \(a + b > n\):约束过紧,"前面不少于 \(a\)"成为主导限制,合法位置从 \(a+1\) 开始到 \(n\),共 \(n-a\)
    • 计数技巧:合法位置数量 = 右端点 \(n\) - 左端点 \(\max(a+1, n-b)\) + \(1\),通过分类讨论简化计算
    • 适用于区间约束求解、边界条件分析类计数问题

【算法标签】

数学

【代码详解】

#include <bits/stdc++.h>
using namespace std;
int t;

int main()
{
    cin >> t;
    for (int i = 1; i <= t; i++)
    {
        int n, a, b;
        cin >> n >> a >> b;
        // 分三种情况计算
        if (a + b == n)
        {
            cout << b << endl;  // 如果刚好坐满,则b的个数就是b
        }
        if (a + b < n)
        {
            cout << b + 1 << endl;  // 如果还有空位,b可以多坐一个人
        }
        if (a + b > n)
        {
            cout << n - a << endl;  // 如果座位不够,剩余的座位全给b
        }
    }
    return 0;
}

【运行结果】

2
3 1 1
2
5 2 3
3
posted @ 2026-07-05 17:13  团爸讲算法  阅读(2)  评论(0)    收藏  举报