zoukankan      html  css  js  c++  java
  • USACO 2011 November Cow Lineup /// map set 尺取法 oj25279

    题目大意:

    输入n 接下来n行描述n头牛的编号num和品种id

    得到包含所有id的最短段 输出最短段的编号差

    Sample Input

    6
    25 7
    26 1
    15 1
    22 3
    20 1
    30 1

    Sample Output

    4

    Hint

    INPUT DETAILS:

    There are 6 cows, at positions 25,26,15,22,20,30, with respective breed IDs 7,1,1,3,1,1.

    OUTPUT DETAILS:

    The range from x=22 up through x=26 (of total size 4) contains each of the distinct breed IDs 1, 3, and 7 represented in FJ's herd.

    有思路而不会代码实现也是够痛苦

    将牛按num排序后

    15 20 22 25 26 30

    1   1    3   7   1   1

    将15为段头 直到段尾为25时符合要求出现了所有id

    但 id 1 出现过两次 所以可以缩小该段 将段头移向下一位20

    此时为符合要求的最小段 保存当前段的编号差

    将段头移向下一位 继续移动段尾

    直到符合要求进行判断 更新保存最小的编号差

    #include <bits/stdc++.h>
    using namespace std;
    struct Cow{ int num,id; }cow[50005]; 
    map <int,int> m; /// 记录id出现的次数
    set <int> id_set; /// 记录出现过的品种id 得到一共有多少种品种
    bool cmp(Cow q,Cow p)
    {
        return q.num<p.num; 
    } /// 结构体按编号num排序 不会重复所以不需考虑相等
    int main()
    {
        /// num_map为符合要求的一段的该段当前id数 
        /// num_id为该队中的所有id数
        /// head tail为当前该段的段头和段尾
        int n,num_id,num_map,head,tail,mini;
        while(~scanf("%d",&n))
        {
            id_set.clear(); m.clear();
            for(int i=0;i<n;i++)
            {
                scanf("%d%d",&cow[i].num,&cow[i].id);
                m[cow[i].id]=0; id_set.insert(cow[i].id);
            }
            sort(cow,cow+n,cmp);
    
            num_id=id_set.size();  /// set可以去重 即所有id数
            head=tail=num_map=0;  
            mini=0x3f3f3f3f;
    
    //        for(int i=1;i<=n;i++)
    //            printf("%d %d
    ",cow[i].num,cow[i].id);
    //        printf("
    ");
    
            while(1)
            {
                while(num_map!=num_id && tail<n)
                {
                    if(m[cow[tail].id]==0) num_map++; 
                    m[cow[tail++].id]++;
                    /// 如果此id没出现过则该段当前id数+1
                    /// m记录该段id出现次数
                } /// 持续记录id,直到该段当前id数为所有id数 或 已到队尾
    
                if(tail==n && num_map!=num_id) break;
                /// 已到队尾 且 不存在符合要求的组合 则跳出
    
                while(m[cow[head].id ]>1)
                    m[cow[head++].id ]--; 
                /// 当前id数 为 所有id数 若段头的id在该段中出现次数>1
                /// 则可缩小该段长度 段头可移到下一位
                /// 如 13312 这种情况可缩小该段长度到 312
    
                mini=min(mini,cow[tail-1].num-cow[head].num);
    
                m[cow[head++].id]--; num_map--;
                /// 继续遍历后面有无符合要求的组合 
                /// 段头移到下一位 该段中当前id数-1
            }
            printf("%d
    ",mini);
        }
    
        return 0;
    }
    /*
    6
    25 7
    26 1
    15 1
    22 3
    20 1
    30 1
    */
    View Code

     ...原来这是尺取法

    再加种写法 ...虽然差不多

            while(head<=tail&&tail<=n)
            {
                if(num_map<num_id)
                {
                    if(m[cow[tail].id]==0) num_map++;
                    m[cow[tail++].id]++;
                }
                else if(num_map==num_id)
                {
                    while(m[cow[head].id]>1)
                        m[cow[head++].id]--;
                    mini=min(mini,cow[tail-1].num-cow[head].num);
                    m[cow[head++].id]--; num_map--;
                }
            }    
    View Code
  • 相关阅读:
    1380. Lucky Numbers in a Matrix
    672. Bulb Switcher II
    1375. Bulb Switcher III
    1376. Time Needed to Inform All Employees
    1372. Longest ZigZag Path in a Binary Tree
    PHP中curl_multi并发详解【转】
    php中$_REQUEST、$_POST、$_GET的区别【转】
    Post请求的两种编码格式:application/x-www-form-urlencoded和multipart/form-data【转】
    PHP $_FILES函数详解【转】
    php接收二进制流【转】
  • 原文地址:https://www.cnblogs.com/zquzjx/p/8583565.html
Copyright © 2011-2022 走看看