fzu 2216

Problem 2216 The Longest Straight

Problem Description

ZB is playing a card game where the goal is to make straights. Each card in the deck has a number between 1 and M(including 1 and M). A straight is a sequence of cards with consecutive values. Values do not wrap around, so 1 does not come after M. In addition to regular cards, the deck also contains jokers. Each joker can be used as any valid number (between 1 and M, including 1 and M).

You will be given N integers card[1] .. card[n] referring to the cards in your hand. Jokers are represented by zeros, and other cards are represented by their values. ZB wants to know the number of cards in the longest straight that can be formed using one or more cards from his hand.

Input

The first line contains an integer T, meaning the number of the cases.

For each test case:

The first line there are two integers N and M in the first line (1 <= N, M <= 100000), and the second line contains N integers card[i] (0 <= card[i] <= M).

Output

For each test case, output a single integer in a line -- the longest straight ZB can get.

Sample Input

2
7 11
0 6 5 3 0 10 11
8 1000
100 100 100 101 100 99 97 103

5
3

Source

3  5  6  10  11  和0  之间的关系。  那么我们可以转化一下  设一个sum 数组（当然是递增的，所以我们就可以 用二分）表示  从第数字1到数字i  其中 缺少的 个数字的个数，也就是 我们需要的0 的个数 （因为0 可以去变成每一个数字 ） 然后我们就可以枚举左端点  然后二分去找到右端点，，二分的  要找的位置  就是我们当前点为左端点 ，根据我们手中现在有的 0 的个数 就可以找到我们可以用0 去填补的最长连续子序列可以到哪个位置。  然后相减就是最大长度。

#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define N 100005

using namespace std;

int card[N];
int zero;
int n,m;

int main()
{
int T;
scanf("%d",&T);
while(T--)
{
cin>>n>>m;
zero=0;
int x;
memset(card,0,sizeof(card));

for(int i=1;i<=n;i++)
{
scanf("%d",&x);
if(x==0) zero++;
card[x]++;
}

for(int i=1;i<=m;i++){
if(card[i]){
card[i]=card[i-1];
}
else{
card[i]=card[i-1]+1;
}
}

int ans=1;
for(int i=1;i<=m;i++)
{
int ind=upper_bound(card+1,card+m+1,zero+card[i-1])-(card+1);
ind++;
ans=max(ans,ind-i);
}

printf("%d\n",ans);

//cout<<ans<<endl;
}

return 0;
}

• 评论

• 上一篇
• 下一篇