• CodeForces 91B Queue


    题目链接:http://codeforces.com/contest/91/problem/B

    题目大意:

      有n头大象排队买票,第i头大象的年龄为ai,如果有比他年轻的大象排在他前面,这头大象就会非常不高兴,衡量不高兴度的指标是这只大象与排在前面的最远的比它年轻的大象之间的大象数量。输出每只大象的不高兴度,如果没有不高兴,输出-1。

    分析:

    单调栈+愉快的二分
    这道题是求最远小的问题,而单调栈只能求最近小,我思考了半天能不能把最近小改造成求最远小,结果很是徒劳。
    随后我发现,求第i只大象右边的最远小,难道不就是把大象拎到队伍最右边,然后求它左边的最近小吗?也就是说只要让队伍过一下单调栈(我用数组实现的),然后对于每头大象,在单调栈里剩下来的元素中做一次二分查找(查找第一个比他小的)即可。

    代码如下:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3  
     4 #define rep(i,n) for (int i = 0; i < (n); ++i)
     5 #define For(i,s,t) for (int i = (s); i <= (t); ++i)
     6 #define rFor(i,t,s) for (int i = (t); i >= (s); --i)
     7 #define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
     8 #define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i)
     9  
    10 #define pr(x) cout << #x << " = " << x << "  "
    11 #define prln(x) cout << #x << " = " << x << endl
    12  
    13 #define ALL(x) x.begin(),x.end()
    14 #define INS(x) inserter(x,x.begin())
    15  
    16 #define ms0(a) memset(a,0,sizeof(a))
    17 #define msI(a) memset(a,inf,sizeof(a))
    18 #define msM(a) memset(a,-1,sizeof(a))
    19  
    20 #define pii pair<int,int> 
    21 #define piii pair<pair<int,int>,int> 
    22 #define mp make_pair
    23 #define pb push_back
    24 #define fi first
    25 #define se second
    26  
    27 inline int gc(){
    28     static const int BUF = 1e7;
    29     static char buf[BUF], *bg = buf + BUF, *ed = bg;
    30      
    31     if(bg == ed) fread(bg = buf, 1, BUF, stdin);
    32     return *bg++;
    33 } 
    34  
    35 inline int ri(){
    36     int x = 0, f = 1, c = gc();
    37     for(; c<48||c>57; f = c=='-'?-1:f, c=gc());
    38     for(; c>47&&c<58; x = x*10 + c - 48, c=gc());
    39     return x*f;
    40 }
    41  
    42 typedef long long LL;
    43 typedef unsigned long long uLL;
    44 const int inf = 0x3f3f3f3f;
    45 const LL infLL = 0x3f3f3f3f3f3f3f3fLL;
    46 const LL mod = 1e9 + 7;
    47 const int maxN = 1e5 + 7;
    48  
    49 int n;
    50 int a[maxN];
    51 int ans[maxN];
    52  
    53 // 二分查找vector中最右边使得a[x[i]] < k的x[i]值,找不到返回-1 
    54 int BinarySearch(vector< int > & x, int k) {
    55     if(x.size() == 0 || a[x[0]] >= k) return -1;
    56     int l = 0, r = x.size() - 1;
    57     int mid = (l + r) >> 1;
    58      
    59     while(l < r) {
    60         if(a[x[mid]] >= k) {
    61             r = mid - 1;
    62             mid = (l + r) >> 1;
    63         }
    64         else {
    65             l = mid + 1;
    66             if(a[x[l]] >= k) return x[mid];
    67             mid = (l + r) >> 1;
    68         }
    69     }
    70     return x[r]; 
    71 }
    72  
    73 int main(){
    74     while(cin >> n) {
    75         For(i, 1, n) cin >> a[i];
    76         vector< int > vi;
    77          
    78         For(i, 1, n) {
    79             if(vi.empty() || a[i] > a[vi.back()]) {
    80                 vi.push_back(i);
    81             }
    82             else if(a[i] <= a[vi.back()]) {
    83                 vi.pop_back();
    84                 --i;
    85             }
    86         }
    87          
    88         For(i, 1, n) {
    89             ans[i] = BinarySearch(vi, a[i]);
    90             ans[i] -= i + 1;
    91             if(ans[i] < 0) ans[i] = -1;
    92             cout << ans[i] << " ";
    93         }
    94     }
    95     return 0;
    96 }
    View Code
  • 相关阅读:
    递归判断回文
    从小工到专家阅读笔记1
    建立SQL全文索引提升搜索速度
    数据库SQLServer经验小记
    [转]C#中调用SQL存储过程(带输入输出参数的例子)
    20101124 14:55 全文索引是解决海量数据模糊查询的较好解决办法
    使用SQL Server 2008提供的表分区向导
    千万级SQL Server数据库表分区的实现
    C#调用存储过程简单完整例子
    SQL server 海量数据库的查询优化及分页算法(收藏)
  • 原文地址:https://www.cnblogs.com/zaq19970105/p/10752235.html
Copyright © 2020-2023  润新知