• P2564 [SCOI2009]生日礼物


    *传送

    *预处理:把m个区间合并成一个大区间(按照横坐标排序即可)

    *思路:因为我们要一段尽可能小的区间包含所有的彩带种类,我们不防开一个数组,记录当前区间内每种彩带多有多少个,从[1,1]开始,如果当前彩带种类<k,则右端点向右移,把该种彩带在区间内的数量+1,如果该种彩带的数量从0->1,即说明这是一条新彩带,彩带种类+1,当彩带种类==m时,记录下当前区间长度,把左端点向右移,把该种彩带在区间内的数量-1,如果该种彩带的数量从1->0,说明该种彩带不包含在区间里。彩带种类-1

    代码如下:

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <queue>
     5 #include <cmath>
     6 using namespace std;
     7 int n,m,a[1000005],b[20005],k,l,r,t,ans=0;
     8 struct node{
     9     int pos,val;
    10 }num[1000005];
    11 bool cmp(node a,node b){
    12     return a.pos<b.pos;
    13 }
    14 int main()
    15 {
    16 
    17     scanf("%d%d",&n,&m);
    18     for(int i=1;i<=m;i++){
    19         scanf ("%d",&t);
    20         for (int j = 1;j <= t;j++){
    21             scanf ("%d",&num[++ans].pos);
    22             num[ans].val=i;
    23         }
    24     }
    25     sort(num+1,num+ans+1,cmp);
    26     l=1; r=1; k=1; b[num[1].val]=1; int tmp=2000000005;
    27     while(l<=r && r<=n){
    28         while(k==m){
    29             tmp=min(tmp,num[r].pos-num[l].pos);
    30             b[num[l].val]--;
    31             if(b[num[l].val]==0) k--;
    32             l++;
    33         }
    34         r++, b[num[r].val]++;
    35         if(b[num[r].val]==1) k++;
    36     }
    37     cout<<tmp<<endl;
    38     return 0;
    39 }
  • 相关阅读:
    Linux定时任务
    linux文件权限
    grep awk sed 三剑客
    用户管理
    find查找inode号删除文件
    find 查找文件或目录 及du命令
    11、注册新用户
    10、密码扩展,使用Flask-Login认证用户
    9、大型程序的结构
    8、目前flask程序结构
  • 原文地址:https://www.cnblogs.com/very-beginning/p/12491130.html
Copyright © 2020-2023  润新知