题目描述:
所谓同花顺,就是指一些扑克牌,它们花色相同,并且数字连续。现在我手里有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
数据范围
1<=n<=100000。
1<=ai,bi<=1000000000。
思路:
找一段符合条件的最长同花上升子序列,看能否将其他牌改变后插入其中。
题解:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
struct cc{
int hs,num;
}a[100000+10];
int cmp(cc aa,cc bb)//按花色和大小从小到大排序
{
if(aa.hs==bb.hs)
{
return aa.num<bb.num;
}
return aa.hs<bb.hs;
}
int n;
int solve()
{
int ans=0;//最长序列长度
int sum=0;//序列中空隙大小
int cnt=1;//当前序列长度
for(int i=1;i<=n;i++)
{
if((a[i].hs==a[i-1].hs)&&(a[i].num-a[i-1].num-1+sum<=n-cnt-1))
{
sum+=a[i].num-a[i-1].num-1;
if(a[i].num!=a[i-1].num)//去重
{
cnt++;
}
}
else//前后花色不同或者序列中的空隙的大小超过了不在序列中的牌的数目
{
ans=max(ans,cnt);
sum=0,cnt=1;
}
}
ans=max(ans,cnt);
return n-ans;
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
scanf("%d%d",&a[i].hs,&a[i].num);
}
sort(a+1,a+n+1,cmp);
printf("%d",solve());
return 0;
}
2247

被折叠的 条评论
为什么被折叠?



