码迷,mamicode.com
首页 > 其他好文 > 详细

找连续数

时间:2015-06-02 21:45:57      阅读:92      评论:0      收藏:0      [点我收藏+]

标签:

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);
        }
    }
}                    
View Code

 

技术分享
#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]);
    }
}
View Code

 

找连续数

标签:

原文地址:http://www.cnblogs.com/Lzy2015/p/4547543.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!