尺取法1——加set,map

继续上节;
poj3320;
http://poj.org/problem?id=3320
题目大意;求复习最少的连续页数,但包含所有的知识点;
输入为;有几页,每页包含什么知识点;(1 ≤ P ≤ 1000000);
输出;最少连续的但可以全部复习到的页数;

首先要确定要使用set,map,和尺取法;
set;因为知识都是单一的;满足用set来存储;————set的大小就是知识点的个数;
map;因为每页都对应着一个知识点;存在映射关系;————map对应着每个知识点有多少页了;
尺取法;应用于求最优连续子序列;所以他也当仁不让;————查找最优子序列;
先看代码;

//尺取法加set,map; 
#include<stdio.h>
#include<cmath>
#include<algorithm> 
#include<map>
#include<set>

using namespace std;
int a[1000005]; 
int main()
{
    set<int> c;
    map<int,int> cnt;
    int n, i, m;
    while(scanf("%d",&n) != EOF){
        for(i = 0; i < n; i++){
            scanf("%d",&a[i]);
            c.insert(a[i]);
        }
        m = c.size();
         int l = 0 , r = 0 , ans = n+1,sum = 0;
        while(1){
            while(r < n && sum < m)
                if(cnt[a[r++]]++ == 0)//寻找遇到了好多知识点; 
                    sum++;
            if(sum < m)break;//条件不满足了,跳出输出最小页数
            ans = min(ans,r-l);//记录最小的页数(之前最小页数和这次查询的页数) 
            if(--cnt[a[l++]] == 0)//如果只出现一次的时候就减去;;; 
                sum--;
        }
        printf("%d\n",ans); 
    }
    return 0;
} 

主要还是来研究尺取法吧;

        while(1){
            while(r < n && sum < m)
                if(cnt[a[r++]]++ == 0)//寻找遇到了好多知识点; 
                    sum++;
            if(sum < m)break;//条件不满足了,跳出输出最小页数
            ans = min(ans,r-l);//记录最小的页数(之前最小页数和这次查询的页数) 
            if(--cnt[a[l++]] == 0)//如果只出现一次的时候就减去;;; 
                sum--;
        }

大循环while(1);是为了进行多次查找;
中间的小while是为了进行移动查找;
1,直到找到所有知识点也就是sum=m时,则进行下面的记录最小页数并考虑是否向前移动;
2,或者是直到搜索完毕,r=n并且存在sum

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值