java解法

出现次数为 4 的卡片:按卡片值降序排列。
出现次数为 3 的卡片:按卡片值升序排列,并尽量与出现次数为 2 的卡片配对。
出现次数为 2 的卡片:按卡片值升序排列。
出现次数为 1 的卡片:按卡片值降序排列。
关键步骤:
统计每张卡片的出现次数:使用 Map 来统计每个卡片的出现次数。
分类:将卡片按出现次数分类为 1 次、2 次、3 次和 4 次。
排序:
按照题目要求,对每个分类的卡片进行排序:
对 4 次出现的卡片按出现次数和卡片值降序排序。
对 3 次和 2 次出现的卡片按升序排序。
对 1 次出现的卡片按降序排序。
拼接结果:根据排序后的卡片,将它们按顺序加入最终结果列表。
在处理 3 次出现的卡片时,优先配对 2 次出现的卡片或单张卡片。

import java.util.*;
import java.util.stream.Collectors;  // 添加此行,允许使用Stream API进行集合转换

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        List<Integer> numbers = new ArrayList<>();
        // 读取输入直到输入结束
        while (sc.hasNextInt()) {
            numbers.add(sc.nextInt());
        }
        // 输出处理后的卡片排列顺序
        System.out.println(processCards(numbers));
    }

    // 处理卡片排列的函数
    public static String processCards(List<Integer> numbers) {
        // Step 1: 统计每张卡片的出现次数
        Map<Integer, Integer> count = new HashMap<>();
        for (int num : numbers) {
            count.put(num, count.getOrDefault(num, 0) + 1);
        }

        // Step 2: 将卡片按出现次数分组
        Set<Integer> singles = new HashSet<>();
        Set<Integer> pairs = new HashSet<>();
        Set<Integer> triples = new HashSet<>();
        Set<Integer> quads = new HashSet<>();

        // 遍历出现次数统计,分配到相应的集合中
        for (Map.Entry<Integer, Integer> entry : count.entrySet()) {
            int num = entry.getKey();
            int freq = entry.getValue();
            if (freq == 1) {
                singles.add(num);  // 1次出现的卡片
            } else if (freq == 2) {
                pairs.add(num);    // 2次出现的卡片
            } else if (freq == 3) {
                triples.add(num);  // 3次出现的卡片
            } else {
                quads.add(num);    // 4次出现的卡片
            }
        }

        // Step 3: 创建一个结果列表,存放排序后的卡片
        List<Integer> result = new ArrayList<>();

        // 处理出现次数为4的卡片,按出现次数和卡片值降序排列
        List<Integer> quadsList = new ArrayList<>(quads);
        quadsList.sort((a, b) -> count.get(b) != count.get(a) ? count.get(b) - count.get(a) : b - a);
        for (int q : quadsList) {
            for (int i = 0; i < count.get(q); i++) {
                result.add(q);  // 将出现次数为4的卡片添加到结果中
            }
        }

        // Step 4: 处理出现次数为3的卡片,并尽量与2次的卡片配对
        List<Integer> triplesList = new ArrayList<>(triples);
        List<Integer> pairsList = new ArrayList<>(pairs);
        Collections.sort(triplesList);  // 对出现次数为3的卡片升序排序
        Collections.sort(pairsList);    // 对出现次数为2的卡片升序排序

        while (!triplesList.isEmpty()) {
            int t = triplesList.remove(triplesList.size() - 1);  // 从列表末尾取出3次的卡片
            result.add(t);  // 将3次的卡片添加到结果中
            result.add(t);  // 添加两次
            result.add(t);  // 添加三次

            // 判断是否能和二次的卡片配对,或者如果没有二次卡片则与单次卡片配对
            if (!triplesList.isEmpty() && (pairsList.isEmpty() || triplesList.get(triplesList.size() - 1) > pairsList.get(pairsList.size() - 1))) {
                int leftover = triplesList.remove(triplesList.size() - 1);  // 从3次卡片中移除一个
                singles.add(leftover);  // 将剩余卡片的一个值放入单张卡片的集合中
                result.add(leftover);   // 添加剩余的单张卡片
                result.add(leftover);   // 再添加一次
            } else if (!pairsList.isEmpty()) {
                int p = pairsList.remove(pairsList.size() - 1);  // 从二次卡片中取出一个卡片
                result.add(p);  // 添加到结果中
                result.add(p);  // 再添加一次
            }
        }

        // Step 5: 处理出现次数为2的卡片
        while (!pairsList.isEmpty()) {
            int p = pairsList.remove(pairsList.size() - 1);  // 从二次卡片中取出一个
            result.add(p);  // 添加到结果中
            result.add(p);  // 再添加一次
        }

        // Step 6: 处理出现次数为1的卡片,按降序排列
        List<Integer> singlesList = new ArrayList<>(singles);
        singlesList.sort(Collections.reverseOrder());  // 将单张卡片按降序排列
        result.addAll(singlesList);  // 添加到结果中

        // 返回处理后的结果,使用空格连接
        return result.stream().map(String::valueOf).collect(Collectors.joining(" "));
    }
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C++解法

出现次数为 4 的卡片:按卡片值降序排列。
出现次数为 3 的卡片:按卡片值升序排列,并尽量与出现次数为 2 的卡片配对。
出现次数为 2 的卡片:按卡片值升序排列。
出现次数为 1 的卡片:按卡片值降序排列。
关键步骤:
统计每个卡片的出现次数:使用 map 来记录每个卡片的出现次数。
分类:将卡片按照出现次数分为 1 次、2 次、3 次和 4 次。
排序:
对 4 次出现的卡片按卡片值降序排列。
对 3 次和 2 次出现的卡片按卡片值升序排列。
对 1 次出现的卡片按降序排列。
拼接结果:根据排序后的卡片,将它们按顺序加入最终结果列表。
在处理 3 次出现的卡片时,优先配对 2 次的卡片或单张卡片。

#include 
#include 
#include 
#include 

using namespace std;

int main() {
    // 存储所有输入的卡片
    vector<int> ns;
    int x;

    // 读取所有输入直到输入结束
    while (cin >> x) {
        ns.push_back(x);  // 将每个输入的整数加入到 ns 向量中
    }
    
    // 使用 map 来统计每张卡片出现的次数
    map<int, int> cnt;
    for (int n : ns) {
        cnt[n]++;  // 每次遇到相同的卡片,计数加 1
    }

    // 创建四个向量用于存储不同出现次数的卡片
    vector<int> sng, prs, trs, bms;

    // 根据卡片的出现次数将卡片分类
    for (auto& e : cnt) {
        int v = e.first;  // 卡片的值
        int c = e.second;  // 卡片的出现次数
        if (c == 1) {
            sng.push_back(v);  // 1 次出现的卡片
        } else if (c == 2) {
            prs.push_back(v);  // 2 次出现的卡片
        } else if (c == 3) {
            trs.push_back(v);  // 3 次出现的卡片
        } else {
            bms.push_back(v);  // 4 次及以上出现的卡片
        }
    }

    // 结果存储卡片的最终顺序
    vector<int> res;
    
    // Step 1: 对出现次数为 4 次的卡片按卡片值降序排序
    sort(bms.begin(), bms.end(), [&](int a, int b) {
        if (cnt[a] != cnt[b]) return cnt[a] > cnt[b];  // 如果出现次数不同,按照次数排序
        return a > b;  // 如果次数相同,按卡片值降序排序
    });

    // 将排序后的 4 次出现的卡片加入结果
    for (int b : bms) {
        for (int i = 0; i < cnt[b]; ++i) {
            res.push_back(b);  // 按照出现次数将卡片添加到结果中
        }
    }

    // Step 2: 对 3 次和 2 次出现的卡片按升序排列
    sort(trs.begin(), trs.end());  // 3 次的卡片升序排序
    sort(prs.begin(), prs.end());  // 2 次的卡片升序排序

    // Step 3: 处理出现次数为 3 的卡片
    while (!trs.empty()) {
        int t = trs.back();  // 取出 3 次出现的卡片
        trs.pop_back();  // 从 3 次卡片集合中移除
        res.push_back(t);  // 将其加入结果
        res.push_back(t);  // 再添加一次
        res.push_back(t);  // 再添加一次

        // Step 4: 配对 3 次卡片,优先配对 2 次卡片,如果没有配对,则与单张卡片配对
        if (!trs.empty() && (prs.empty() || trs.back() > prs.back())) {
            sng.push_back(trs.back());  // 将 3 次卡片剩余的一个加入单张卡片集合
            res.push_back(trs.back());  // 将其加入结果
            res.push_back(trs.back());  // 再添加一次
            trs.pop_back();  // 从 3 次卡片中移除
        } else if (!prs.empty()) {
            res.push_back(prs.back());  // 如果有 2 次卡片,配对 2 次卡片
            res.push_back(prs.back());  // 再添加一次
            prs.pop_back();  // 从 2 次卡片中移除
        }
    }

    // Step 5: 处理 2 次出现的卡片
    while (!prs.empty()) {
        res.push_back(prs.back());  // 将 2 次出现的卡片添加到结果
        res.push_back(prs.back());  // 再添加一次
        prs.pop_back();  // 从 2 次卡片中移除
    }

    // Step 6: 处理 1 次出现的卡片,按降序排序
    sort(sng.begin(), sng.end(), greater<int>());  // 1 次出现的卡片按降序排列
    for (int s : sng) {
        res.push_back(s);  // 将 1 次卡片加入结果
    }

    // 输出结果
    for (int i = 0; i < res.size(); ++i) {
        if (i > 0) cout << " ";  // 每个卡片之间加空格
        cout << res[i];  // 输出卡片值
    }
    cout << endl;  // 输出换行符

    return 0;
}

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

C解法

更新中
 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

JS解法

出现次数为 4 次的卡片:按照卡片值降序排列。
出现次数为 3 次的卡片:按照卡片值升序排列,并尽量与出现次数为 2 次的卡片配对。
出现次数为 2 次的卡片:按照卡片值升序排列。
出现次数为 1 次的卡片:按照卡片值降序排列。
关键步骤:
统计每个卡片的出现次数:使用对象(cnt)来记录每个卡片的出现次数。
分类:将卡片按照出现次数分为 1 次、2 次、3 次和 4 次。
排序:
对 4 次出现的卡片按卡片值降序排列。
对 3 次和 2 次出现的卡片按卡片值升序排列。
对 1 次出现的卡片按降序排列。
拼接结果:根据排序后的卡片,将它们按顺序加入最终结果列表。
在处理 3 次出现的卡片时,优先配对 2 次的卡片或单张卡片。
输出结果:最后将拼接后的卡片输出。

// 使用 readline 库来读取输入
const rl = require("readline").createInterface({ input: process.stdin });
const it = rl[Symbol.asyncIterator](); // 获取异步迭代器
const rdl = async () => (await it.next()).value; // 获取每一行的输入

void (async function () {
  // 读取输入的数字并将其转换为数字数组
  const nums = (await rdl()).split(" ").map(Number);

  // 创建一个对象用于统计每个卡片的出现次数
  const cnt = {};
  nums.forEach((n) => (cnt[n] = (cnt[n] || 0) + 1));

  // 创建四个数组用于分类存储不同出现次数的卡片
  const sng = [], prs = [], tpl = [], bmb = [];
  // 遍历计数对象,根据出现次数分类
  for (const val in cnt) {
    const c = cnt[val];  // 出现次数
    const v = parseInt(val);  // 卡片值
    if (c === 1) sng.push(v);  // 1 次出现的卡片
    else if (c === 2) prs.push(v);  // 2 次出现的卡片
    else if (c === 3) tpl.push(v);  // 3 次出现的卡片
    else bmb.push(v);  // 4 次及以上出现的卡片
  }

  // 存储最终结果的数组
  const res = [];
  
  // Step 1: 对出现次数为 4 次的卡片按卡片值降序排序
  bmb.sort((x, y) => (cnt[x] !== cnt[y] ? cnt[y] - cnt[x] : y - x)); // 按照频率和卡片值排序
  bmb.forEach((v) => res.push(...Array(cnt[v]).fill(v)));  // 将 4 次出现的卡片加入结果数组

  // Step 2: 对出现次数为 3 次的卡片按卡片值升序排序
  tpl.sort((x, y) => x - y);
  // 对出现次数为 2 次的卡片按卡片值升序排序
  prs.sort((x, y) => x - y);

  // Step 3: 处理 3 次出现的卡片
  while (tpl.length > 0) {
    // 将一个 3 次出现的卡片加入结果
    res.push(...Array(3).fill(tpl.pop()));
    
    // Step 4: 配对 3 次卡片,优先配对 2 次卡片,如果没有配对,则与单张卡片配对
    if (tpl.length > 0 && (prs.length === 0 || tpl.at(-1) > prs.at(-1))) {
      sng.push(tpl.at(-1));  // 将 3 次卡片剩余的一个加入单张卡片集合
      res.push(...Array(2).fill(tpl.pop()));  // 将剩余的 2 个卡片加入结果
    } else if (prs.length > 0) {
      res.push(...Array(2).fill(prs.pop()));  // 如果有 2 次卡片,配对 2 次卡片
    }
  }

  // Step 5: 处理 2 次出现的卡片
  while (prs.length > 0) {
    res.push(...Array(2).fill(prs.pop()));  // 将 2 次出现的卡片加入结果
  }

  // Step 6: 处理 1 次出现的卡片,按降序排序
  sng.sort((x, y) => y - x);  // 1 次出现的卡片按降序排列
  res.push(...sng);  // 将 1 次卡片加入结果

  // 输出结果,卡片之间用空格隔开
  console.log(res.join(" "));
})();

 class="hljs-button signin active" data-title="登录复制" data-report-click="{"spm":"1001.2101.3001.4334"}">

注意:

如果发现代码有用例覆盖不到的情况,欢迎反馈!会在第一时间修正,更新。
解题不易,如对您有帮助,欢迎点赞/收藏

注:本文转载自blog.csdn.net的CodeClimb的文章"https://blog.csdn.net/CodeClimb/article/details/144772568"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接

评论记录:

未查询到任何数据!