B 同花顺

题目描述
所谓同花顺,就是指一些扑克牌,它们花⾊相同,并且数字连续。
现在我手里有n 张扑克牌,但它们可能并不能凑成同花顺。我现在想知道,最
少更换其中的多少张牌,我能让这n 张牌都凑成同花顺?
输入格式
第一行一个整数n,表⽰扑克牌的张数。
接下来n 行,每行两个整数ai 和bi。其中ai 表示第i 张牌的花色,bi 表示第
i 张牌的数字。
输出格式
一行一个整数,表示最少更换多少张牌可以达到目标。
样例输入 1
5
1 1
1 2
1 3
1 4
1 5
样例输出 1
0
样例输入 2  
5
1 9
1 10
2 11
2 12
2 13
样例输出2
2
数据范围
对于30% 的数据,n ≤ 10。
对于60% 的数据,n ≤ 10^5,1 ≤ ai ≤ 10^5,1 ≤ bi ≤ n。
对于100% 的数据,n ≤ 10^5,1 ≤ ai, bi ≤ 10^9。
补充:
所谓“数字连续”,是指像这样:“4,5,6,7,8,9”。而形如“4,5,5,6,7,8,
9”(有重复数字)是不叫“连续”的。
输入数据中可能会有完全相同的牌。两张完全相同的牌是不应该出现在同一个
同花顺中的。  
分析:

题目大意
给定n张扑克牌的花色和数字,问最少替换多少张牌,可以全部凑成同花顺?
30%
爆搜即可
60%
首先我们要进行去重(相同的牌只保留一张)
取花色出现次数最多的那种牌就可以
100%
仍然是要排序去重
枚举我们同花顺在已有的牌里面的最后一张牌
寻找可能的第一张牌
不对啊,这是O(n^2)的
寻找“可能的第一张牌”的时候,有一个小技巧
令last为当前牌的最后一张牌时,“可能的第一张牌”
如果当前牌的数值是a,last这张牌的数值是b,则显然要满足a-b+1
≤n;  
如果我们的数值都是排好序的,随着我们“最后一张牌”的递增,“可能的第一张牌”显然是不降的

代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int maxn=100000+5;
struct card
{
    int a,b;
    bool operator <(const card& x) const {//重载小于运算符,sort函数要用到
        return a==x.a? b<x.b : a<x.a;
    }
    bool operator ==(const card& y) const {//重载等于运算符,unique函数要用到
        return (a==y.a&&b==y.b);
    }
} cd[maxn];
int n,m;
int solve(int s,int t)
{
    int i,j,ret=0;
    for(i=j=s;i<=t;++i)
    {
        while(j<t&&cd[j+1].b-cd[i].b<n) ++j;
        ret=max(ret,j-i+1);
    }
    return ret;
}
int main()
{
    freopen("card.in", "r", stdin);
    freopen("card.out", "w", stdout);
    int i,j,ans=0;
    scanf("%d",&n);
    for(i=1;i<=n;i++)
        scanf("%d%d",&cd[i].a,&cd[i].b);
    sort(cd+1,cd+n+1);
    m=unique(cd+1,cd+n+1)-cd-1;
    for(i=2,j=1;i<=m;i++)
    if(cd[i].a!=cd[i-1].a) {
        ans=max(ans,solve(j,i-1));
        j=i;
    }
    ans=max(ans,solve(j,i-1));
    printf("%d",n-ans);
    fclose(stdin);
    fclose(stdout);
    return 0;
}

还有通过本题我发现了一个有趣的东西:
int i;
    for(i=1;i<=6;i++)//一个有意思的小实验,for循环语句执行时只执行到6,但i到最后变成了7;
    {}
    cout<<i<<endl;
输出7;

推断for循环语句就等于:
i=1;
    while(i<=6) i++; 
 cout<<i<<endl;
但是for循环与while语句不同的是: 
在循环语句中for循环实际执行了6次, 而while语句执行了7次。

或者是:
do
{
  i++;
 }while(i<=6);
 cout<<i<<endl
这就与for循环语句相同了。


### 同花顺逆向工程分析方法 #### 数据流跟踪与变量生成路径确认 在进行同花顺逆向工程的过程中,首要目标是对软件内部的数据流动进行全面的理解。这可以通过栈追踪技术来完成,即定位到关键变量的生成位置,并进一步追溯这些变量在整个程序运行期间是如何被创建和使用的。这种方法能够清晰地展示出变量从无到有的整个生命周期及其加密逻辑[^2]。 #### 动态调试工具的应用 为了更深入地研究同花顺客户端的行为模式,在实际操作中可以借助动态调试工具如`objection`来进行探索性测试。例如命令 `$ objection -g com.lechuan.mdwz explore` 可用于启动一个交互式的shell环境,从而允许开发者检查特定类(比如 MethodPatchEntry 类)是否已经被成功加载至内存之中[^3]。这种手段对于验证假设以及收集实时数据非常有效。 #### Python API 的数据分析能力补充 除了传统的反编译技术和动态分析之外,还可以考虑结合现代编程语言所提供的强大功能来增强我们的工作效率。特别是当涉及到大量复杂金融数据处理时,使用像 Python 这样的高级脚本语言配合专门设计好的第三方库(如同花顺官方提供的API),不仅可以简化许多繁琐的任务,而且还能提高最终结果的质量。需要注意的是,在依赖此类接口前应详细了解它们的工作原理、性能表现等方面的信息以便做出合理的选择[^4]。 #### 自定义函数实现案例分享 最后值得一提的例子来自于 C++ 领域的一个简单项目——CreateDll 工程展示了如何构建最基本的 Windows 平台下共享库文件(.dll),其中包含了对外暴露的功能入口 `sum()` 函数原型声明部分采用了标准C兼容的方式(`extern "C"` 关键字修饰)加上导出属性标记(_declspec(dllexport))共同作用使得其他应用程序可以直接调用该DLL内的公共成员;而具体实现体则保持常规做法即可满足基本需求[^5]。 ```cpp // CreateDll.cpp extern "C" _declspec(dllexport) int sum(int a, int b); int sum(int a, int b) { return a + b; } ``` 以上内容综合运用了多种不同层面的技术要点,旨在提供一套较为完整的思路框架供参考学习之用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值