HDU 5247 找连续数 (思维题)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5247 找连续数 (思维题)相关的知识,希望对你有一定的参考价值。


找连续数

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2004    Accepted Submission(s): 741


 

Problem Description

小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的。

现在小度熊增加题目难度,他不想知道是否有这样的 k 的区间,而是想知道有几个这样的 k 的区间。

 

 

Input

输入包含一组测试数据。

第一行包含两个整数n,m,n代表数组中有多少个数字,m 代表针对于此数组的询问次数,n不会超过10的4次方,m 不会超过1000。第二行包含n个正整数,第 I 个数字代表无序数组的第 I 位上的数字,数字大小不会超过2的31次方。接下来 m 行,每行一个正整数 k,含义详见题目描述,k 的大小不会超过1000。

 

 

Output

第一行输"Case #i:"。(由于只有一组样例,只输出”Case #1:”即可)

然后对于每个询问的 k,输出一行包含一个整数,代表数组中满足条件的 k 的大小的区间的数量。

 

 

Sample Input


 


6 2 3 2 1 4 3 5 3 4

 

 

Sample Output


 


Case #1: 2 2

 

 

Source

​2015年百度之星程序设计大赛 - 初赛(1)​

 

 

Recommend

hujie

分析:这题肯定要预处理满足区间长度为k的序列的个数,用ans[k]保存,因为多组访问,且就一组样例。

           预处理暴力枚举会超时,需要一点思维,首先想想排序可以用什么来替代,连续的数,我们可以这么理解:里面没有重复数,且数的最大值-最小值==数的数量,以为数太大,所以开一个map记录数的多少,但是入门这么依据按照三重循环暴力枚举的话,依旧会超时,但我们会发现我们不需要枚举第一层的长度,因为数的数量就是长度。

 

#include <stdio.h>
#include<algorithm>
#include<string.h>
#include<map>
#define N 1000005
using namespace std;
typedef long long ll;
#define INF 0xffffff
ll n,m;
ll a[N],b[N];
ll ans[N];

int main()

int n,t;
int c=1;
while(scanf("%d %d",&n,&t)!=EOF)

int i,j,k;
printf("Case #%d:\\n",c++);
for(i=1;i<=n;i++)

scanf("%d",&a[i]);


map<ll,ll>mp;
for(int j=1;j<=n;j++)

long long maxx=-1,minn=INF;

mp.clear();
for(int k=j;k<=n;k++)

mp[a[k]]++;
if(mp[a[k]]>1)

break;

maxx=max(a[k],maxx);
minn=min(a[k],minn);

if(maxx-minn==k-j)
//cout<<maxx<<" "<<minn<<" "<<k<<" "<<j<<endl;
ans[k-j+1]++;



while(t--)

scanf("%d",&k);
printf("%lld\\n",ans[k]);


return 0;

   

以上是关于HDU 5247 找连续数 (思维题)的主要内容,如果未能解决你的问题,请参考以下文章

hdu No.5247 找连续数

Just Random HDU - 4790 思维题(打表找规律)分段求解

第四场 hdu 6069 Counting Divisors (逆向思维)

hdu7095 Add or Multiply 1(思维,组合数学,第二类斯特林数预处理)

第八场 hdu 6143 Killer Names(思维题)

HDU 4869 Turn the pokers(思维+逆元)