zoukankan      html  css  js  c++  java
  • bzoj1293[SCOI2009]生日礼物 尺取法

    1293: [SCOI2009]生日礼物

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2838  Solved: 1547
    [Submit][Status][Discuss]

    Description

    小西有一条很长的彩带,彩带上挂着各式各样的彩珠。已知彩珠有N个,分为K种。简单的说,可以将彩带考虑为x轴,每一个彩珠有一个对应的坐标(即位置)。某些坐标上可以没有彩珠,但多个彩珠也可以出现在同一个位置上。 小布生日快到了,于是小西打算剪一段彩带送给小布。为了让礼物彩带足够漂亮,小西希望这一段彩带中能包含所有种类的彩珠。同时,为了方便,小西希望这段彩带尽可能短,你能帮助小西计算这个最短的长度么?彩带的长度即为彩带开始位置到结束位置的位置差。

    Input

    第一行包含两个整数N, K,分别表示彩珠的总数以及种类数。接下来K行,每行第一个数为Ti,表示第i种彩珠的数目。接下来按升序给出Ti个非负整数,为这Ti个彩珠分别出现的位置。

    Output

    应包含一行,为最短彩带长度。

    Sample Input

    6 3
    1 5
    2 1 7
    3 1 3 8

    Sample Output

    3

    HINT

    有多种方案可选,其中比较短的是1~5和5~8。后者长度为3最短。
    【数据规模】
    对于50%的数据, N≤10000;
    对于80%的数据, N≤800000;
    对于100%的数据,1≤N≤1000000,1≤K≤60,0≤彩珠位置<2^31。

    尺取法

     1 //尺取法
     2 #include<cstdio>
     3 #include<iostream>
     4 #include<cstring>
     5 #include<algorithm>
     6 #define N 1000005
     7 #define ll long long
     8 using namespace std;
     9 int n,m,cnt,vis[70],q[N];
    10 struct node{
    11     int p,c;
    12     bool operator < (const node &b)const{
    13         return p<b.p; 
    14     }
    15 }t[N];
    16 char gc(){
    17     static char s[1000000],*p1,*p2;
    18     if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
    19     if(p1==p2)return EOF;
    20     return *p1++;  
    21 }
    22 int read(){
    23     int x=0;char ch=gc();
    24     while(ch>'9'||ch<'0')ch=gc();
    25     while(ch<='9'&&ch>='0')x=x*10+ch-'0',ch=gc();
    26     return x; 
    27 }
    28 
    29 int main(){
    30     n=read();m=read();
    31     for(int i=1;i<=m;i++){
    32          int x=read();
    33          for(int j=1;j<=x;j++){
    34              int p=read();
    35              t[++cnt]=(node){p,i};
    36          }
    37     }
    38     sort(t+1,t+1+cnt);
    39     int l=1,r=0,num=0;
    40     int ans=2147483647;
    41     while(r<n){
    42         while(num<m&&r<n){
    43             if(!vis[t[++r].c])num++;
    44             vis[t[r].c]++; 
    45         }
    46         if(r>n)break;
    47         while(num>=m&&l<=r){
    48             ans=min(ans,t[r].p-t[l].p);
    49             ;if(!--vis[t[l++].c])num--; 
    50         }
    51     }
    52     printf("%d
    ",ans);
    53     return 0;
    54 }
  • 相关阅读:
    HDU 1102 Constructing Roads
    HDU 1285 确定比赛名次。
    最小生成树 HDU 各种畅通工程的题,prim和kru的模板题
    HDU Jungle Roads 1301 最小生成树、
    并查集小结(转)
    HDU hdu 2094 产生冠军 拓扑排序 判定环
    模运算(转)
    拓扑排序(主要是确定环和加法) HDU 2647 Reward
    HDU 1372 Knight Moves 简单BFS
    用计算机模型浅析人与人之间沟通方式 (一)如何谈话
  • 原文地址:https://www.cnblogs.com/wsy01/p/8107959.html
Copyright © 2011-2022 走看看