当前位置:首页 > 洛谷 > 洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化

1周前 (07-07)

洛谷2652题解析:同花顺排序问题的动态规划与滑动窗口优化 洛谷题解 同花顺算法 动态规划 滑动窗口 扑克牌排序 C++ 第1张

一、题目解读

洛谷2652题要求对一组扑克牌进行排序,目标是找到最少需要调整的次数,使得所有牌形成同花顺。题目中,扑克牌由花色和数字组成,需先按花色排序,再在同花色内按数字排序。核心难点在于如何处理花色与数字的组合排序,以及如何高效寻找最优调整次数。

二、解题思路

采用以下思路:

1. 定义Card结构体存储花色和数字;

2. 自定义比较函数,优先按花色排序,同花色按数字排序;

3. 遍历排序后的牌组,找到相同花色的连续区间;

4. 对区间内数字去重,利用滑动窗口找到最长连续子序列;

5. 通过子序列长度计算调整次数,动态更新最小值。

三、解题步骤

1. 输入牌组数量n,读取每张牌的花色和数字;

2. 调用sort函数,基于自定义比较函数进行排序;

3. 遍历牌组,使用双指针定位同花色区间;

4. 对区间内数字去重,并存储到临时数组

5. 通过滑动窗口(左右指针)计算最长连续子序列长度;

6. 更新最小调整次数min_changes = min(min_changes, n - 子序列长度);

7. 输出最终结果。

四、代码与注释

#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;

struct Card {
    int suit;  // 花色
    int num;   // 数字
};

// 比较函数:先按花色排序,同花色按数字排序
bool cmp(const Card& a, const Card& b) {
    if(a.suit!= b.suit) return a.suit < b.suit;
    return a.num < b.num;
}

int main() {
    int n;
    cin >> n;
    vector<Card> cards(n);
    
    for(int i = 0; i < n; i++) {
        cin >> cards[i].suit >> cards[i].num;
    }
    
    // 按花色和数字排序
    sort(cards.begin(), cards.end(), cmp);
    
    int min_changes = n; // 初始化为最大可能值
    
    // 遍历所有可能的同花顺区间
    for(int i = 0; i < n; ) {
        int j = i;
        // 找到相同花色的连续区间
        while(j < n && cards[j].suit == cards[i].suit) j++;
        
        vector<int> nums;
        for(int k = i; k < j; k++) {
            nums.push_back(cards[k].num);
        }
        
        // 去重
        sort(nums.begin(), nums.end());
        nums.erase(unique(nums.begin(), nums.end()), nums.end());
        
        // 滑动窗口找最长连续序列
        int left = 0;
        for(int right = 0; right < nums.size(); right++) {
            while(nums[right] - nums[left] >= n) left++;
            min_changes = min(min_changes, n - (right - left + 1));
        }
        
        i = j;
    }
    
    cout << min_changes << endl;
    return 0;
}

五、总结

本解法结合排序、去重与滑动窗口技术,通过动态规划思想高效求解。核心在于将问题拆解为同花色区间的连续子序列查找,利用滑动窗口降低时间复杂度。算法时间复杂度为O(nlogn),空间复杂度为O(n)。实际应用中,可进一步优化窗口移动逻辑或采用更高效的数据结构

参考:牛客2652题解

原创内容 转载请注明出处

分享给朋友:

相关文章

力扣53题:贪心策略与动态规划的完美联姻 三行代码映射算法精髓

力扣53题:贪心策略与动态规划的完美联姻 三行代码映射算法精髓

题目理解在数字的海洋中寻找最具价值的珍珠链:当我们面对一个可能包含正负数的数组时,寻找连续子数组的和最大值就像在波动的股票曲线中捕捉最佳投资时段。问题的核心在于如何处理可能降低总和的负值元素——是忍痛...

力扣第92题:三步定位 精准反转链表指定区间

力扣第92题:三步定位 精准反转链表指定区间

题目解读给定一个单链表和两个整数left与right,要求将链表中从第left个节点到第right个节点的部分进行反转,而保持其他部分不变。例如,对于链表1→2→3→4→5,left=2,right=...

力扣1137题:动态规划解泰波那契数 高效求解第N项的秘密

力扣1137题:动态规划解泰波那契数 高效求解第N项的秘密

一:重新解读题目泰波那契数列是一个充满数学趣味的递推序列:从第3项开始,每个数均为前三个数的和(即Tₙ₊₃ = Tₙ + Tₙ₊₁ + Tₙ₊₂)。当给定整数n时,需要高效计算出第n项的值。面对此类递...

牛客12576题解题全解析:动态规划+质因数分解实现跳跃问题最优解

牛客12576题解题全解析:动态规划+质因数分解实现跳跃问题最优解

一、题目解读牛客12576题是一道经典的算法题,要求给定起点N和终点M,求解从N到M的最少跳跃次数。题目考察的核心在于路径优化与动态规划思想,需结合数论中的质因数分解技巧,通过合理设计算法降低时间复杂...

【蓝桥杯2015省赛解析】生命之树:树形DP解题全攻略(洛谷P8625代码详解)

【蓝桥杯2015省赛解析】生命之树:树形DP解题全攻略(洛谷P8625代码详解)

一、题目解读    “生命之树”是一道经典的树形结构问题,要求计算一棵带权树中,以某个节点为根的最大子树权值和。题目输入为n个节点及边信息,每个节点有权值wi,...

洛谷P4999题解析:动态规划求解数字拆分与求和问题(附代码)

洛谷P4999题解析:动态规划求解数字拆分与求和问题(附代码)

一、题目解读洛谷P4999题要求处理给定区间 [L, R] 内数字的拆分与求和问题。每个数字需拆分为其各位数字之和,并计算区间内所有数字之和的累加结果。题目需考虑大数情况,并采用取模运算(MOD=1e...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。