zoukankan      html  css  js  c++  java
  • 51nod1112(xjb)

    題目鏈接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1112

    題意:中文題誒~

    思路:對於函數 f(x) = a + kx,對於x足夠大的情況下,顯然f(x)的值的相對大小是只受 k 影響的.對於 n 條這樣的直線最多可以發生 (n-1)*n/2 次超越;

    不過本題只要求輸出前 1e4 次超越,所以可以先二分出1e4次超越的時間點(這部分是用來優化常數的),然後再枚舉每一次超越即可.這樣的時間復雜

    度爲 O(n^2),對於 1e4 的數據量只要常數小一點還是能過的...

    代碼:

     1 #include <iostream>
     2 #include <stdio.h>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 const int MAXN = 1e4+10;
     7 const int inf = 1e4;
     8 pair<int, int> p[MAXN];//存儲開始時的數據
     9 pair<int, int> p1[MAXN];//存儲1e4時間點的數據
    10 pair<double, pair<int, int> > p2[MAXN*10];//存儲答案
    11 int vis[MAXN*10], n;
    12 
    13 int get_times(int mid){ //計算在k時間點可以達到的超越次數
    14     int ans = 0;
    15     for(int i=0; i<n; i++){
    16         p1[i].first = p[i].first + p[i].second * mid;
    17         p1[i].second = i;
    18     }
    19     sort(p1, p1+n);
    20     for(int i=0; i<n; i++){
    21         if(p1[i].second < i){
    22             ans += i-p1[i].second;
    23         }
    24     }
    25     return ans;
    26 }
    27 
    28 void get_time(void){ //二分出達到1e4次超越的時間點
    29     int l=0, r=MAXN*10;
    30     int ans=0;
    31     while(l < r-1){
    32         int mid = (l+r)>>1;
    33         int cnt = get_times(mid);
    34         if(cnt == inf) break;
    35         else if(cnt > inf) r = mid;
    36         else l = mid;
    37     }
    38 }
    39 
    40 int main(void){
    41     scanf("%d", &n);
    42     for(int i=0; i<n; i++){
    43         scanf("%d%d", &p[i].first, &p[i].second);
    44         vis[p[i].first] = i+1;
    45     }
    46     sort(p, p+n);
    47     get_time();
    48     int indx=0;
    49     for(int i=0; i<n; i++){
    50         int a2 = p[p1[i].second].first;
    51         for(int j=0; j<i; j++){
    52             int a1 = p[p1[j].second].first;
    53             if(a1 > a2){
    54                 int b1 = p[p1[j].second].second;
    55                 int b2 = p[p1[i].second].second;
    56                 double k = (a1-a2)*1.0/(b2-b1); //本次超越的時間點
    57                 p2[indx].first = k;
    58                 p2[indx].second.first = vis[a2];
    59                 p2[indx++].second.second = vis[a1];
    60             }
    61         }
    62     }
    63     if(!indx){
    64         printf("No Solution
    ");
    65     }else{
    66         sort(p2, p2+indx);
    67         int cnt = min(indx, inf);
    68         for(int i=0; i<cnt; i++){
    69             printf("%d %d
    ", p2[i].second.first, p2[i].second.second);
    70         }
    71     }
    72     return 0;
    73 }
    View Code
  • 相关阅读:
    JUC01
    Linux
    逆向工程核心原理——第三十四章
    逆向工程核心原理——第三十三章
    逆向工程核心原理——第三十二章
    逆向工程核心原理——第三十章
    逆向工程核心原理——第二十八章
    逆向工程核心原理——第二十七章
    逆向工程核心原理——第二十四章
    逆向工程核心原理——第二十三章
  • 原文地址:https://www.cnblogs.com/geloutingyu/p/6869604.html
Copyright © 2011-2022 走看看