找连续数

http://acm.hdu.edu.cn/viewcode.php?rid=13825114

rmq预处理

单调队列维护最大最少值

还有一个暴力的做法

#include <algorithm>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>
#include<cstdlib>
#include<math.h>
#include<iostream>
#include<limits.h>
#include <sstream>
#define ll long long
#define clr(a) memset(a,0,sizeof(a))
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define inf 1e17

using namespace std;

int n,m;
int a[10005];
int b[10005];
map <ll,int>mp;
int vis[10005];
int dpmin[10005][17];
int dpmax[10005][17];
int f[10005];

inline int input()
{
    char ch;
    ch = getchar();
    while(ch < ‘0‘ || ch >‘9‘)
    {
        ch = getchar();
    }
    int ret = 0;
    while(ch >= ‘0‘ && ch <= ‘9‘)
    {
        ret *= 10;
        ret += ch -‘0‘;
        ch = getchar();
    }
    return ret;
}

void init()
{
    for (int i=1;i<=n;i++) dpmin[i][0]=dpmax[i][0]=a[i];
    int mm=log2(n);
    for (int j=1;j<=mm;j++)
    for (int i=1;(i+(1<<j)-1)<=n;i++)
    dpmin[i][j]=min(dpmin[i][j-1],dpmin[i+(1<<(j-1))][j-1]),
    dpmax[i][j]=max(dpmax[i][j-1],dpmax[i+(1<<(j-1))][j-1]);
}

int rmqmax(int l,int r)
{
    int k=log2(r-l+1);
    return max(dpmax[l][k],dpmax[r-(1<<k)+1][k]);
}
int rmqmin(int l,int r)
{
    int k=log2(r-l+1);
    return min(dpmin[l][k],dpmin[r-(1<<k)+1][k]);
}

int main()
{
    int k;

    scanf("%d%d",&n,&m);
    {
        mp.clear();
        puts("Case #1:");
        for(int i =1; i <= n; i++)
        {
            a[i] = input();
            b[i] = a[i];
        }
        sort(b+1,b+1+n);
        int nn = unique(b+1,b+1+n) - (b+1);

        for(int i =1; i <= nn; i++)
        {
            mp[b[i]] = i;
        }
        for(int i =1; i <= n; i++)
            f[i] = mp[a[i]];
        init();
        for(int j = 1;j <= m; j++)
        {
            int ans = 0;
            scanf("%d",&k);
            clr(vis);
            if(k == 1)
            {
                printf("%d\n",n);
                continue;
            }
            if(k > n)
            {
                printf("0\n");
                continue;
            }
            int minx = rmqmin(1,k);
            int maxx = rmqmax(1,k);
            int co = 0;
            for(int i =1; i <= k; i++)
            {

                vis[f[i]]++;
                if(vis[f[i]] == 2) co++;
               //重复的点的处理手法,这里wa了几次
            }
            if(maxx - minx + 1 == k && !co)
                ans++;
            for(int i = 2; i <= n - k+1; i++)
            {

//                    3 2 5 3 3
//                    第一次判断 3 2 5 3,break
//                    vis[3] = 0;
//                    2 5 3 3 误认为成立
//                int xu = mp[a[i-1]];
//                vis[xu] = 0;
//                xu = mp[a[i+k-1]];
//                if(vis[xu]) break;
//                else
//                    vis[xu] = 1;
//                int minx = rmqmin(i,k+i-1);
//                int maxx = rmqmax(i,k+i-1);
//                if(maxx - minx + 1 == k)
//                    ans++;
                int xu = f[i-1];
                vis[xu]--;
                if(vis[xu]==1) co--;
                xu = f[i+k-1];
                vis[xu]++;
                if(vis[xu] == 2) co++;
                minx = rmqmin(i,k+i-1);
                maxx = rmqmax(i,k+i-1);
                if(maxx - minx + 1 == k && !co)
                    ans++;
            }
            printf("%d\n",ans);
        }
    }
}                    

#include <algorithm>
#include <string.h>
#include <ctype.h>
#include <stdio.h>
#include <string>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <set>
#include <map>
#include<cstdlib>
#include<math.h>
#include<iostream>
#include<limits.h>
#include <sstream>
#define ll long long
#define clr(a) memset(a,0,sizeof(a))
#define lson l , m , rt << 1
#define rson m + 1 , r , rt << 1 | 1
#define inf 0x3f3f3f3f
#define N 10005

using namespace std;

int a[N];
int b[N];
int vis[N];
map <int,int> mp;
int ans[N];

int main()
{
    int n,m;
    scanf("%d%d",&n,&m);
    mp.clear();
    clr(vis);
    clr(ans);
    puts("Case #1:");
    for(int i =1; i <= n; i++)
    {
        scanf("%d",a+i);
        b[i] = a[i];
    }
    sort(b+1,b+1+n);
    int nn = unique(b+1,b+1+n) - b - 1;
    for(int i =1; i <= nn; i++)
    {
        mp[b[i]] = i;
    }
    int fl = 0;
    for(int i = 1;i <= n; i++)
    {
        int minx = inf;
        int maxx = -inf;
        fl++;
        for(int k = 0; k +i <= n && k <= 1000; k++)
        {
            int xu = mp[a[k+i]];
            if(vis[xu]==fl)break;
            vis[xu] = fl;
            minx = min(minx,a[i+k]);
            maxx = max(maxx,a[i+k]);
            if(maxx - minx == k)
                ans[k+1]++;
        }
    }
    for(int i = 1; i <= m; i++)
    {
        int d;
        scanf("%d",&d);
        printf("%d\n",ans[d]);
    }
}

时间: 2024-08-18 05:56:51

找连续数的相关文章

2015年百度之星初赛(1) --- B 找连续数

找连续数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 179    Accepted Submission(s): 65 Problem Description 小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的. 现在小度熊增加题目难度,他不想知道是否有这样的 k 的区

百度之星 2015 初赛(1) 1002 找连续数

找连续数 Accepts: 401 Submissions: 1911 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description 小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的. 现在小度熊增加题目难度,他不想知道是否有这样的 k 的区间,而是想知道有几个这样的 k 的区间. Input

hdu 5247 找连续数(思维)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5247 找连续数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1207    Accepted Submission(s): 435 Problem Description 小度熊拿到了一个无序的数组,对于这个数组.小度熊想知道能否找到一

HDU 5247 找连续数 (set妙用)

找连续数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 1008    Accepted Submission(s): 362 Problem Description 小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的. 现在小度熊增加题目难度,他不想知道是否有这样的 k

2015 百度之星 1002 找连续数 暴力

找连续数 Time Limit: 20 Sec  Memory Limit: 256 MB 题目连接 http://acdream.info/problem?pid=1751 Description 小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的. 现在小度熊增加题目难度,他不想知道是否有这样的 k 的区间,而是想知道有几个这样的 k 的区间. Input 输入包含一组测试数据. 第一行包含两个整数n,m,n代表数组中有多少个数

HDU 5247 找连续数(RMQ+滑窗)

找连续数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 281    Accepted Submission(s): 102 Problem Description 小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的. 现在小度熊增加题目难度,他不想知道是否有这样的 k

HDU5247找连续数(百度之星初赛)

找连续数 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 677    Accepted Submission(s): 253 Problem Description 小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的. 现在小度熊增加题目难度,他不想知道是否有这样的 k

编程之美第二题 找连续数

题意:   就是给你一个乱序序列,  现在要找某个特定序列的个数,   某特定序列的要求为  该序列长度为k   且序列中为连续的序列   例如 13245  就为1-5的连续序列 题解: 没啥解法   ,  两重for 暴力,就是这样 代码: #include<stdio.h> #include<iostream> #include<algorithm> #include<map> #include<string.h> using namesp

hdu5247 找连续数

Problem Description 小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的. 现在小度熊增加题目难度,他不想知道是否有这样的 k 的区间,而是想知道有几个这样的 k 的区间. Input 输入包含一组测试数据. 第一行包含两个整数n,m,n代表数组中有多少个数字,m 代表针对于此数组的询问次数,n不会超过10的4次方,m 不会超过1000.第二行包含n个正整数,第 I 个数字代表无序数组的第 I 位上的数字,数字大小

hdu 5247 找连续数【暴力枚举】

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5247 分析:这道题是2015百度之星初赛1的2题,当时没看这道题 是队友看的,比完以后也做了一下,思路大体都是一样的,就是 暴力枚举,因为k<=1000,那么我们可以每一点x为起点跑[x,x+999] 这段区间,把每得到一段连续的子区间[x,?],则num[len]++(len=size([x,?])); 这样就可以了,最后num数组里就是对应的答案 献上代码: #include<stdio.h&