P316. 【例54.1】 奇数单增序列

https://ok.hn.cn/p/P316

注意:
1.题目要求的是从小到大输出奇数,所以在输出奇数前要进行排序
2.题目要求的输出间隔是’,‘,这里我们可以用一个sum变量,当sum>0时输出’,‘以及奇数
通俗理解:第一个数只单独输出,后面的数输出’,‘以及奇数

#include <bits/stdc++.h>
using namespace std;
typedef long long l;

l n, a[100010], sum;

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);
	cin >> n;
	for (l i = 1; i <= n; i++)
		cin >> a[i];
	sort(a + 1, a + 1 + n);//从小到大排序
	for (l i = 1; i <= n; i++) 
		if (a[i] % 2) {//当a[i]为奇数时执行输出
			if (sum)
				cout << ',';
			cout << a[i];
			sum++;
		}

	return 0;
}

P317. 【例54.2】 学生组队

https://ok.hn.cn/p/P317

这道题的整体思路是先对学生的能力值进行排序,然后遍历相邻的学生,计算他们之间的能力值差值,并累加这些差值。最终累加的结果就是学生们至少还需要做多少道题才能组成两两能力值相同的队伍。
具体步骤如下:

  1. 读取学生的数量n和每个学生的能力值。
  2. 对学生的能力值进行排序,可以使用快速排序算法或其他排序算法。
  3. 遍历学生的能力值数组,从第1个学生开始,每次跳过一个学生(因为需要两两组队)。
  4. 在遍历的过程中,计算相邻两个学生的能力值差值,并将差值累加到一个变量sum中。
  5. 遍历结束后,sum的值即为学生们至少还需要做多少道题才能组成两两能力值相同的队伍。
  6. 输出sum的值作为结果。
    请注意,这道题的关键点是要理解题目要求的”能力值相同的两人才能组队”,并且需要对学生的能力值进行排序以便计算差值。另外,由于输入的学生数量是偶数,所以不需要考虑奇数个学生无法组成队伍的情况。
#include <bits/stdc++.h>  
using namespace std;
typedef long long l;  
l n, a[100010], sum;
int main() {
    ios::sync_with_stdio(false); 
    cin.tie(0); cout.tie(0);
    cin >> n;  
    for (l i = 1; i <= n; i++)  
        cin >> a[i];
    sort(a + 1, a + 1 + n);  // 对学生的能力值进行排序
    for (l i = 1; i <= n; i += 2)  // 遍历计算每对学生的能力值差值
        sum += (a[i + 1] - a[i]);
    cout << sum; 
    return 0;
}

P318. 练54.1 6084问题

https://ok.hn.cn/p/P318

思路解释:

1.首先,读取一个四位数n。
2.将四位数的每一位提取出来,并按照从小到大的顺序放入数组a中。
3.根据数组a的元素构造最大数和最小数,从而得到最大数nummax和最小数nummin。
4.计算最大数和最小数之间的差值,即nummax - nummin。
5.输出差值作为结果。

#include <bits/stdc++.h>  
using namespace std;
typedef long long l;  

l n, a[100010], nummax, temp, i, nummin;  

int main() {
    ios::sync_with_stdio(false);  
    cin.tie(0); cout.tie(0); 
    cin >> n; 
    temp = n;
    while (temp)  // 将输入的四位数的每一位提取出来放入数组a中
        ++i, a[i] = temp % 10, temp /= 10;
    sort(a + 1, a + 5);  // 对数组a中的元素进行排序
    for (l i = 4; i; i--)  // 构造最大数
        nummax = nummax * 10 + a[i];
    for (l i = 1; i < 5; i++)  // 构造最小数
        nummin = nummin * 10 + a[i];
    cout << nummax - nummin;  // 输出差值

    return 0;
}

P319. 练54.2 小科的三角形

https://ok.hn.cn/p/P319

勾股定理指出,在一个直角三角形中,直角边的平方和等于斜边的平方。根据这个定理,我们可以用勾股定理来判断一个三角形是否为直角三角形。

代码的思路如下:

1.首先,读取三条边的长度。
2.对三条边的长度进行排序,将最小边放在a[1],次小边放在a[2],最大边放在a[3]。
3.判断是否为直角三角形:

*如果a[1] * a[1] + a[2] * a[2]等于a[3] * a[3],则说明是直角三角形。
如果不等于,则说明不是直角三角形。

如果是直角三角形,则输出直角三角形斜边的平方,即a[3] * a[3]。
如果不是直角三角形,则输出以任意两条边为直角边的直角三角形的斜边平方的最大值,即a[2] * a[2] + a[3] * a[3]。*

#include <bits/stdc++.h>  
using namespace std;
typedef long long l;

l n, a[1000010];  

int main() {
    ios::sync_with_stdio(false); 
    cin.tie(0); cout.tie(0);  
    cin >> a[1] >> a[2] >> a[3]; 
    sort(a + 1, a + 4);  // 对边长进行排序
    if (a[1] * a[1] + a[2] * a[2] == a[3] * a[3])  // 判断是否为直角三角形
        cout << a[3] * a[3];  // 输出直角三角形斜边的平方
    else
        cout << a[2] * a[2] + a[3] * a[3];  // 输出以任意两条边为直角边的直角三角形的斜边平方的最大值

    return 0;
}

P320. 练54.3 竞选总统

https://ok.hn.cn/p/P320

代码思路:
1.首先,读取一个整数n,表示Y国的州数。
2.循环读取每个州的选民数,并将其存储在数组a中。
3.对选民数进行排序,以便按照从小到大的顺序计算至少需要赢得的选民数。
4.判断州数n是否为偶数,如果是偶数,则设置一个标记flag为1。
5.遍历前一半的州,计算每个州至少需要赢得的选民数,并累加到sum中。
6.如果某个州的选民数为偶数,则多赢得1个选民。
7.输出至少需要赢得的选民数sum。

#include <bits/stdc++.h>  
using namespace std;
typedef long long l;

l n, a[1000010], sum; 

int main() {
    ios::sync_with_stdio(false); 
    cin.tie(0); cout.tie(0);  
    while (cin >> n and n) {  // 循环读取输入直到n为0
        sum = 0;  // 初始化sum为0
        for (l i = 1; i <= n; i++)  // 读取每个州的选民数
            cin >> a[i];
        sort(a + 1, a + 1 + n);  // 对选民数进行排序
        bool flag = 0;  // 初始化标记flag为0
        if (!(n % 2))  // 判断n是否为偶数
            flag = 1;  // 如果是偶数,则将标记flag设为1
        for (l i = 1; i <= ceil(n * 1.0 / 2) + flag; i++) {  // 遍历前一半的州
            sum += ceil(a[i] * 1.0 / 2);  // 将每个州至少需要赢得的选民数累加到sum中
            if (!(a[i] % 2))  // 判断选民数是否为偶数
                sum++;  // 如果是偶数,则再加上1个选民
        }
        cout << sum << '\n';  // 输出至少需要赢得的选民数
    }

    return 0;
}


P321. 练54.4 整数ABC

https://ok.hn.cn/p/P321

思路解释:

1.首先,读取三个整数和字符串s。
2.对三个整数进行排序,将最小的整数放在a[1],次小的整数放在a[2],最大的整数放在a[3]。
3.遍历字符串s的每个字符:
如果字符为’A’,则输出最小的整数a[1]。
如果字符为’B’,则输出次小的整数a[2]。
如果字符为’C’,则输出最大的整数a[3]。

4.输出三个整数,以空格分隔。

#include <bits/stdc++.h> 
using namespace std;
typedef long long l;

l n, a[1000010], sum;  
string s;  

int main() {
    ios::sync_with_stdio(false);  
    cin.tie(0); cout.tie(0); 
    cin >> a[1] >> a[2] >> a[3] >> s;  // 输入三个整数和字符串s
    sort(a + 1, a + 4);  // 对三个整数进行排序
    for (l i = 0; i < s.size(); i++) {  // 遍历字符串s的每个字符
        if (s[i] == 'A')  // 如果字符为'A'
            cout << a[1] << ' ';  // 输出最小的整数a[1]
        else if (s[i] == 'B')  // 如果字符为'B'
            cout << a[2] << ' ';  // 输出次小的整数a[2]
        else
            cout << a[3] << ' ';  // 否则输出最大的整数a[3]
    }

    return 0;
}

P322. 练54.5 损失最小

https://ok.hn.cn/p/P322

思路解释:

1.首先,读取两个正整数n和m,分别表示艺术品的数量和劫匪要求取走的艺术品数量。
2.循环读取每件艺术品的价值,并将其存储在数组a中。
3.对艺术品的价值进行排序,以便按照从小到大的顺序输出给劫匪。
4.输出给劫匪的艺术品价值,输出m行,每行一个整数,表示给出的艺术品价值,需要从小到大输出。

#include <bits/stdc++.h>  
using namespace std;
typedef long long l;

l n, m, a[1000010];  

int main() {
    ios::sync_with_stdio(false);  
    cin.tie(0); cout.tie(0);  
    cin >> n >> m;  
    for (l i = 1; i <= n; i++)  // 读取每件艺术品的价值
        cin >> a[i];
    sort(a + 1, a + 1 + n);  // 对艺术品的价值进行排序
    for (l i = 1; i <= m; i++)  // 输出给劫匪的艺术品价值
        cout << a[i] << '\n';

    return 0;
}