poj3320

#include 
#include 
#include 
# include 

using namespace std;

int a[1000005],p;
set<int>com;
map<int,int>mp;

int main()                  /*尺取法*/
{   //freopen("in.txt","r",stdin);
    cin>>p;
    com.clear();    /*初始化*/
    mp.clear();
    for (int i=1;i<=p;i++)
    {
        scanf("%d",&a[i]);
        com.insert(a[i]);
    }
    int total,sum=0;
    total=com.size();  /*统计不同的数据的个数*/
    int ans=p,left=1,right=1;
    while (left<=p&&right<=p)  /*防止越界*/
    {
        if (mp[a[right]]==0) sum++;  /*统计当前不同数据的个数*/
        mp[a[right]]++;             /*统计每个数据出现的次数*/
        while (mp[a[left]]>1)       /*如果区间的第一个数重复则首指针向后移*/
        {
            mp[a[left]]--;
            left++;
        }
        if (sum==total)      /*找到了一个字串*/
           {
               if (right-left+1<ans) ans=right-left+1;
               if (mp[a[left]]==1) sum--;             /*寻找下一个子序列,首指针向后移*/
               mp[a[left]]--;
               left++;
           }
        right++;   /*考察下一个数*/

    }
    cout << ans << endl;
    return 0;
}
题意:
书一共p页,第i页有一个知识点a[i],同一个知识点可以多次出现,想要读连续的书页把所有的知识点覆盖,求要读的最少的页数
思路:
首先set记录所有的知识点
假设从第s页到第t页刚好覆盖所有知识,记录下一个answear,那么s++继续增大t直到再次覆盖所有的知识,就又得到一个answear,去两个answear的最小值,同理继续增大s

你可能感兴趣的:(尺取法,子序列)