0
点赞
收藏
分享

微信扫一扫

【hihocoder - offer编程练习赛60 B】最大顺子(双指针,思维)

题干:

时间限制:10000ms

单点时限:1000ms

内存限制:256MB

描述

你有N张卡片,每张卡片上写着一个正整数Ai,并且N张卡片上的整数各不相同。  

此外,你还有M张百搭卡片,可以当作写着任意正整数的卡片。

一个“顺子”包含K张卡片,并且满足卡片上的整数恰好是连续的K个正整数。我们将其中最大的整数称作顺子的值。

例如1-2-3-4-5的值是5,101-102-103的值是103。  

请你计算用给定的N张卡片和M张百搭卡片,能凑出的值最大的顺子是多少,并且输出该顺子的值。

输入

第一行包含3个整数,N,M和K。  

第二行包含N个整数,A1, A2, ... AN。  

对于50%的数据,1 ≤ N, K ≤ 1000  

对于100%的数据,1 ≤ N, K ≤ 100000 0 ≤ M < K 0 ≤ Ai ≤ 100000000

输出

一个整数代表答案

样例输入

10 1 5  
1 4 2 8 5 7 10 11 13 3

样例输出

11

解题报告:

 首先不难证明最终答案的左端点一定取在给定的值处。(这个可以贪心证明。)

  然后双指针扫一遍就完事了。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
ll a[MAX];
int main()
{
ll n,m,k,ans;
cin>>n>>m>>k;
for(int i = 1; i<=n; i++) scanf("%lld",a+i);
sort(a+1,a+n+1);
int l=n,r=n;
while(l>=1 && r>=1) {
if(a[l] + k - 1 < a[r]) r--;
else {
if(r - l + 1 >= k - m) {
ans = a[l] + k - 1;break;
}
else l--;
}
}
cout << ans;
return 0 ;
}

双指为了更清晰的表达思路(是对每一个左指针,右指针进行的决策),一般用for循环,可以这么写:

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
const int MAX = 2e5 + 5;
ll a[MAX];
int main()
{
ll n,m,k,ans;
cin>>n>>m>>k;
for(int i = 1; i<=n; i++) scanf("%lld",a+i);
sort(a+1,a+n+1);
int l=n,r=n;
for(;l > 0;--l)
{
while(a[l] + k - 1 < a[r]) r--;
if(r - l + 1 >= k - m){
ans = a[l] + k - 1; break;
}
}
cout << ans;
return 0 ;
}

 


举报

相关推荐

练习赛10(A、B、C、D)

0 条评论