zoukankan      html  css  js  c++  java
  • HDU 5178 Pairs

    pairs

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 96    Accepted Submission(s): 38


    Problem Description
    John has n points on the X axis, and their coordinates are (x[i],0),(i=0,1,2,,n1). He wants to know how many pairs<a,b> that |x[b]x[a]|k.(a<b)
     
    Input
    The first line contains a single integer T (about 5), indicating the number of cases.
    Each test case begins with two integers n,k(1n100000,1k109).
    Next n lines contain an integer x[i](109x[i]109), means the X coordinates.
     
    Output
    For each case, output an integer means how many pairs<a,b> that |x[b]x[a]|k.
     
    Sample Input
    2
    5 5
    -100
    0
    100
    101
    102
    5 300
    -100
    0
    100
    101
    102
     
    Sample Output
    3
    10
     
    Source
     

    首先将所给的坐标从大到小排序,则此题转化为:对排序后的新数列,对每个左边的x[a]找到它右边最远的x[b]使得x[b]-x[a]<=k,累计所有的b-a的和即可。

    这里要做一个小优化,否则直接暴搜会TLE:

      用一个数组pos[i]记录x[i]右边最远的x[b]的b值,由于x[b]是单调递增的,所以找pos[i+1]时只要将b从pos[i]继续往右找即可。

    另外答案结果非常大,应用long long来保存

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<algorithm>
     4 
     5 using namespace std;
     6 
     7 int main()
     8 {
     9     int kase;
    10     scanf ("%d", &kase);
    11     while (kase--)
    12     {
    13         int n, k;
    14         long long ans = 0;
    15         int num[100200], pos[100200];
    16         scanf ("%d %d", &n, &k);
    17         for (int i = 0; i < n; i++)
    18         {
    19             scanf ("%d", &num[i]);
    20         }
    21         sort (num, num + n);
    22         for (int i = 0; i < n; i++)
    23         {
    24             if (i == 0)
    25             {
    26                 for (int j = i + 1; j <= n; j++)
    27                     if ( (j < n && num[j] - num[i] > k) || (j == n))
    28                     {
    29                         pos[i] = j - 1;
    30                         ans += j - i - 1;
    31                         break;
    32                     }
    33             }
    34             else
    35             {
    36                 for (int j = pos[i - 1]; j <= n; j++)
    37                     if ( (j < n && num[j] - num[i] > k) || j == n)
    38                     {
    39                         pos[i] = j - 1;
    40                         ans += j - i - 1;
    41                         break;
    42                     }
    43             }
    44         }
    45         printf ("%I64d
    ", ans);
    46     }
    47     return 0;
    48 }
    [C++]
  • 相关阅读:
    【基础】Oracle基础2
    【基础】Oracle基础1
    【基础】ORACLE中on commit preserve rows和 on commit delete rows的区别
    【函数】ORACLE中MULTISET 的用法
    【基础】ORACLE中的spool 命令
    【基础】ORACLE中substr的用法
    【练习】mysql源码安装
    关于并行执行(parallel executing)的认识
    关于DRM的理解
    打印Excel文件时如何不显示页眉和页脚
  • 原文地址:https://www.cnblogs.com/lzj-0218/p/4306275.html
Copyright © 2011-2022 走看看