FZU 2216 The Longest Straight(最长直道)


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.


ZB正在玩一个纸牌游戏叫做造直道。这幅卡组中的每张卡都有一个1到M间的数字(包括1与M)。一条直道是连续的卡牌序列。值不能循环,因此1不能在M后面。注意除了基本牌外,卡组里还有大小王。每张王可以当成任意一个有效数字(1到M,包括1与M)。

给你N个整数card[1] .. card[n]表示你的手牌。大小王由0表示,其他牌由他们的值表示。ZB想知道自己手牌可以造出的直道最大长度是多少。


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).


输入的首行是一个整数T,表示测试样例的数量。

对于每个测试样例:

第一行有2个整数N和M(1 <= N, M <= 100000),并且第二行有N个整数card[i] (0 <= card[i] <= M)。


Output


输出


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


对于每个测试样例,输出一行一个整数——ZB可以得到的最大直道长度。


Sample Input - 输入样例


Sample Output - 输出样例


2

7 11

0 6 5 3 0 10 11

8 1000

100 100 100 101 100 99 97 103


5

3

【题解】

从数据来看,时间复杂度O(N2)必定爆炸(反正我没优化出来……),请使用O(Nlog2N)。

因此推测出算法,确定左端点(N),二分查(log2N)找在鬼牌允许使用范围内的右端点。

记录当前点前面有多少个0(空缺),然后两端一减就得到需要几张鬼牌填充了。

【代码 C++】

空间比较任性,速度还能优化……

 1 #include<cstdio>
 2 #include<cstring>
 3 int data[100005], sot[100005];
 4 int length(int L, int R, int i0){//[ L, R]
 5     if (L == R){
 6         if (sot[L] || i0) return 1;
 7         return 0;
 8     }
 9     int mid = L + R >> 1;
10     if (data[mid] - data[L - 1] > i0) return length(L, mid, i0);
11     return mid - L + 1 + length(mid + 1, R, i0 - (data[mid] - data[L - 1]));
12 }
13 int main(){
14     int T, N, M, i, j, opt;
15     scanf("%d", &T);
16     while (T--){
17         memset(sot, 0, sizeof(sot));
18         scanf("%d%d", &N, &M);
19         for (data[0] = i = 0; i < N; ++i) scanf("%d", &j), ++sot[j];
20         for (i = 1; i <= M; ++i){
21             if (sot[i]) data[i] = data[i - 1];
22             else data[i] = data[i - 1] + 1;
23         }
24         for (opt = i = 1; i <= M; ++i){
25             j = length(i, M, sot[0]);
26             if (j>opt) opt = j;
27         }
28         printf("%d\n", opt);
29     }
30     return 0;
31 }
时间: 2024-12-14 05:30:18

FZU 2216 The Longest Straight(最长直道)的相关文章

FZU 2216 The Longest Straight 二分

0可以表示任何1到m的数,求一个最长的连续上升序列长度 因为m的范围在10w,所以以每个节点为起点 进行二分,复杂度mlogm 思路:b[i]表示到 1 到 i 有几个数没有出现,二分的时候注意加等号 #include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cstdlib> #include<cmath> #include&l

The Longest Straight(二分,离散化)

 Problem 2216 The Longest Straight Accept: 7    Submit: 14 Time Limit: 1000 mSec    Memory Limit : 32768 KB  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(includi

The Longest Straight(FZUoj2216)

 Problem 2216 The Longest Straight Accept: 82    Submit: 203Time Limit: 1000 mSec    Memory Limit : 32768 KB  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(includ

[CareerCup] 18.7 Longest Word 最长的单词

5.7 Given a list of words, write a program to find the longest word made of other words in the list. 这道题给了我们一个字符串数组,让我们找到最长的那个单词是由字符串数组中的其他单词组成的,LeetCode上跟类似的题目有Word Break和Word Break II.那么我们首先来想如果是拆分两个单词怎么做,那我们要首先把所有的单词存到哈希表里,然后遍历每个单词,每个位置上都拆分成左右两个字符

[LeetCode] Longest Palindrome 最长回文串

Given a string which consists of lowercase or uppercase letters, find the length of the longest palindromes that can be built with those letters. This is case sensitive, for example "Aa" is not considered a palindrome here. Note: Assume the leng

lintcode 容易题:Longest Words 最长单词

题目: 最长单词 给一个词典,找出其中所有最长的单词. 样例 在词典 { "dog", "google", "facebook", "internationalization", "blabla" } 中, 最长的单词集合为 ["internationalization"] 在词典 { "like", "love", "hate"

FZU-2216 The Longest Straight (二分枚举)

题目大意:给n个0~m之间的数,如果是0,那么0可以变为任意的一个1~m之间的一个数.从中选出若干个数,使构成一个连续的序列.问能构成的最长序列的长度为多少? 题目分析:枚举连续序列的起点,二分枚举二分序列的终点. 代码如下; # include<iostream> # include<cstdio> # include<queue> # include<vector> # include<list> # include<map> #

2.3.1 LONGEST PREFIX 最长前缀

题目大意:(如题) 输入输出:(如题) 解题思路: 1.简单动态规划. 2.纠结的边界处理,不建议采用dp[i]表示s前i个字符能否取得这种方法.用这种方法实现字符串储存的时候会比较麻烦.而且如果存储不对边界处理会非常麻烦--(最先我采用的是这种方法,结果WA 4次,多次处理还是有长度为0和长度为1的情况无法分辨,最终放弃) 核心代码: lens=s.length(); for(i=0;i<lens;i++) { for(j=0;j<cntp;j++) { flag=false; len=p[

[LeetCode] 3. Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters. Examples: Given "abcabcbb", the answer is "abc", which the length is 3. Given "bbbbb", the answer is "b", with the length of 1.