zoukankan      html  css  js  c++  java
  • 10.21T6 离散化+二分

    Description

      N头牛站成一行。每头牛有一个不重复的整数x坐标,以及一个整数标识的品种类型。FJ希望找出长度最小的一段,使得每个品种的奶牛至少有一头。

    Input

      第一行: 奶牛数N(1 <= N <= 50,000)..
      行 2..1+N:两个整数,行 j+1表示第 j奶牛的X坐标及种类(范围在32位int内).

    Output

      1行:最短长度

    Sample Input

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

    Sample Output

    4

    Hint

    【样例说明】选出第1、2、4号牛
     
     
    本人做法:
    我用vector记录了一下每个编号的时候的所有位置并排了个序
    然后对于每一个点向右二分每一个不同编号并在里面取最大值,在最大值里面找最小值
    就完了
     
    官方做法:

    模拟扫描法用不更新简单枚举法。维护start—>end区间,记录区间内牛的种类数和每种种类的牛的只数。将牛按坐标排序。

    先固定start,找到符合要求的end并计算结果,之后增加start,再继续找end.由于start与end都只向后扫,则时间复杂度为O(n)

    本人code:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<vector>
     4 #include<algorithm>
     5 #include<map>
     6 #define N 4000005
     7 using namespace std;
     8 vector<int>number[500001],so;
     9 map<int,int>vis;
    10 struct node{
    11     int pos,type;
    12 }e[N];
    13 bool cmp(const node &a,const node&b){
    14     return a.pos<b.pos;
    15 }
    16 int d[50001];
    17 int main(){
    18     int n;
    19     cin>>n;
    20     int cnt=0;
    21     for(int i=1;i<=n;i++){
    22         cin>>e[i].pos>>e[i].type;
    23         d[++cnt]=e[i].type;
    24     }
    25     sort(d+1,d+cnt+1);
    26     cnt=unique(d+1,d+cnt+1)-d-1;
    27     for(int i=1;i<=n;i++){
    28         e[i].type=lower_bound(d+1,d+cnt+1,e[i].type)-d;
    29     }
    30     sort(e+1,e+n+1,cmp);
    31     for(int i=1;i<=n;i++){
    32         number[e[i].type].push_back(e[i].pos);
    33 //        cout<<e[i].type<<" "<<e[i].pos<<'
    ';
    34         if(vis[e[i].type])continue;
    35         so.push_back(e[i].type);
    36         vis[e[i].type]=1;
    37     }
    38     int min0=0x3f3f3f3f;
    39     for(int i=1;i<=n;i++){
    40         int max0=0;
    41         int flag=0;
    42         for(int j=0;j<so.size();j++){
    43             if(e[i].pos>number[so[j]][number[so[j]].size()-1]){
    44                 flag=1;
    45                 break;
    46             }
    47             int pos=lower_bound(number[so[j]].begin(),number[so[j]].end(),e[i].pos)-number[so[j]].begin();
    48             max0=max(max0,number[so[j]][pos]-e[i].pos);
    49         }
    50         if(flag)continue;
    51         min0=min(min0,max0);
    52     }
    53     cout<<min0;
    54     return 0;
    55 }

    官方code:

     1 #include <stdio.h>
     2 #include <stdlib.h>
     3 #include <map>
     4 #include <set>
     5 #include <iostream>
     6 using namespace std;
     7 struct Cow {
     8     int loc, id;
     9 }  cows[50000];
    10 
    11 bool cmp(const Cow &a, const Cow &b) {
    12     return a.loc<b.loc;
    13 }
    14 int main() {
    15     int num_IDS, N, i, num_in_map = 0, A[50000], IDS[50000], start, end, min;
    16     map<int, int> breeds;
    17     set<int> ID_set;
    18     scanf("%d", &N);
    19     for(i=0; i<N; i++) {
    20         scanf("%d %d", &cows[i].loc, &cows[i].id);
    21         ID_set.insert(cows[i].id);
    22         breeds[cows[i].id] = 0;
    23     }
    24     sort(cows, cows+N, cmp);//按坐标排序
    25     num_IDS = ID_set.size();//种类数
    26     start = 0;//开始位置
    27     end = 0;//结束位置
    28     min = 1<<30;//初值
    29     while(1) {
    30         while(num_in_map!=num_IDS && end<N) { //如果未找到包含全部种类区间
    31             if(breeds[cows[end].id]==0) num_in_map++;//映射中如果该类不存在,则加1
    32             breeds[cows[end++].id]++;//记值,结束区间加1
    33         }
    34         if(end==N && num_in_map!=num_IDS)   break;//如果结束了还未找到则退出
    35         while(breeds[cows[start].id]>1)//如果开始位置的牛在区间多于一个,则start加1
    36             breeds[cows[start++].id]--;
    37         //计算stat到end的区间长度并PK原来的
    38         if(cows[end-1].loc-cows[start].loc<min) min = cows[end-1].loc-cows[start].loc;
    39         //新的开始区间,start++,原start的种类减1,区间内总的种类数减1
    40         breeds[cows[start++].id]--;
    41         num_in_map--;
    42     }
    43     printf("%d
    ", min);
    44     return 0;
    45 }

    over

    over

  • 相关阅读:
    Vue 项目刷新当前页面
    Vue 使用 vue-echarts 图表插件
    Vue 路由跳转、传参、接参四种方式
    webpack 之 proxyTable 设置跨域
    二元函数的梯度下降法求解
    2020暑期华为勇敢星实习总结
    时间序列预测算法-ARIMA算法
    航天一院介绍
    腾讯数据分析笔试
    C# Fleck的WebSocket使用
  • 原文地址:https://www.cnblogs.com/saionjisekai/p/9827085.html
Copyright © 2011-2022 走看看