排序入门练习题8 整数奇偶排序 题解

题目出处:《信息学奥赛一本通》第二章上机练习6,略有改编

题目描述

告诉你包含 \(n\) 个数的数组 \(a\) ,你需要把他们按照“奇数排前面,偶数排后面;奇数从从小到大排,偶数从大到小排”的顺序输出。

输入格式

输入的第一行包含一个整数 \(n(1 \le n \le 1000)\)
输入的第二行包含 \(n\) 个整数 \(a_1,a_2,……,a_n\) 。表示数组中的 \(n\) 个元素,两两之间用一个空格分隔。

输出格式

输出占一行,按照“奇数排前面,偶数排后面;奇数从从小到大排,偶数从大到小排”的顺序输出,两个数之间用一个空格分隔。

样例输入

6
1 2 3 4 5 6

样例输出

1 3 5 6 4 2

题目分析

这道题目主要就是考比较函数。
我们需要写一个比较函数,实现如下逻辑:

  • 如果比较的两个数奇偶性不同,则技术应该排前面;
  • 如果两个数都是奇数,小的排前面;
  • 如果两个数都是偶数,大的排前面。

按照这种逻辑,实现的比较函数如下:

bool cmp(int a, int b) {
    if (a % 2 != b % 2) {    // 奇偶性不同
        if (a % 2 == 1) // 说明a奇b偶
            return true;
        else            // 说明a偶b奇
            return false;
    }
    else if (a % 2 == 1) {  // a,b都是奇数
        if (a < b)  // 奇数从小到大排
            return true;
        else return false;
    }
    else {  // a,b都是偶数
        if (a > b)  // 偶数从大到小排
            return true;
        else return false;
    }
}

上面的比较函数过于繁琐,可进行一定的精简,如下:

bool cmp(int a, int b) {
    if (a%2 != b%2) // 如果奇偶性不同
        return a%2 == 1;    // 奇数排前面
    if (a % 2 == 1) // 否则(此时已确定a,b奇偶性相同)
        return a < b;   // 奇数从小到大排
    return a > b;   // 否则(此时已确定a,b都为偶数),偶数从大到小排
}

或者,我们还可以使用更精简一点的写法。
这种写法是只用逻辑运算符来衔接各条件表达式的写法:

bool cmp(int a, int b) {
    return a%2!=b%2&&a%2||a%2&&b%2&&a<b||a%2==0&&b%2==0&&a>b;
}

这个比较函数其实使用了两个逻辑或(||)符号来衔接了三个逻辑表达式,它们分别是:

  • a%2!=b%2&&a%2:奇偶性不同时a为奇数会返回true
  • a%2&&b%2&&a<b:都为奇数时 \(a \lt b\) 会返回true
  • a%2==0&&b%2==0&&a>b:都为偶数时 \(a \gt b\) 会返回true

完整实现代码如下:

#include <bits/stdc++.h>
using namespace std;
int n, a[1001];
bool cmp(int a, int b) {
    return a%2!=b%2&&a%2||a%2&&b%2&&a<b||a%2==0&&b%2==0&&a>b;
}
int main() {
    cin >> n;
    for (int i = 0; i < n; i ++) cin >> a[i];
    sort(a, a+n, cmp);
    for (int i = 0; i < n; i ++) cout << a[i] << " ";
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/zifeiynoip/p/11450520.html