zoukankan      html  css  js  c++  java
  • newcoder假日团队赛8 H-Costume Party

    链接:https://ac.nowcoder.com/acm/contest/1069/H
    时间限制:C/C++ 1秒,其他语言2秒

    空间限制:C/C++ 32768K,其他语言65536K
    64bit IO Format: %lld

    题目描述

    It's Halloween! Farmer John is taking the cows to a costume party, but unfortunately he only has one costume. The costume fits precisely two cows with a length of S (1 <= S <= 1,000,000). FJ has N cows (2 <= N <= 20,000) conveniently numbered 1..N; cow i has length Li (1 <= Li <= 1,000,000). Two cows can fit into the costume if the sum of their lengths is no greater than the length of the costume. FJ wants to know how many pairs of two distinct cows will fit into the costume.

    输入描述:

    * Line 1: Two space-separated integers: N and S
    * Lines 2..N+1: Line i+1 contains a single integer: Li

    输出描述:

    * Line 1: A single integer representing the number of pairs of cows FJ can choose. Note that the order of the two cows does not matter.
    示例1

    输入

    4 6
    3
    5
    2
    1

    输出

    4

    说明

    The four pairs are as follows: cow 1 and cow 3; cow 1 and cow 4; cow 2 and cow 4; and finally cow 3 and cow 4.

    算法思想

      采用哈希的办法先用计数数组把当前状态的分布情况存储下来

      压缩状态从n^2到m

      从上界的一半开始 往左边移动基准

      对于每一个基准 i ,在 i ~ limit - i 范围内(除去当前的元素)的元素都可以与当前元素配对

      每次可以匹配的元素个数用前缀和的形式不断更新

      时间复杂度O(m)

     1 #include <bits/stdc++.h>
     2 #include <iostream>
     3 #include <cstring>
     4 #include <stack>
     5 #include <cstdlib>
     6 #include <queue>
     7 #include <cmath>
     8 #include <cstdio>
     9 #include <algorithm>
    10 #include <string>
    11 #include <vector>
    12 #include <list>
    13 #include <iterator>
    14 #include <set>
    15 #include <map>
    16 #include <utility>
    17 #include <iomanip>
    18 #include <ctime>
    19 #include <sstream>
    20 #include <bitset>
    21 #include <deque>
    22 #include <limits>
    23 #include <numeric>
    24 #include <functional>
    25 
    26 #define gc getchar()
    27 #define mem(a) memset(a,0,sizeof(a))
    28 #define mod 1000000007
    29 #define sort(a,n,int) sort(a,a+n,less<int>())
    30 #define fread() freopen("in.in","r",stdin)
    31 #define fwrite() freopen("out.out","w",stdout)
    32 using namespace std;
    33 
    34 typedef long long ll;
    35 typedef char ch;
    36 typedef double db;
    37 
    38 const int maxn=1e5+10;
    39 const double pi=acos(-1.0);
    40 const int N=1e5+10;
    41 
    42 
    43 ll l[1000005] = {0}; 
    44 int main()
    45 {
    46     ll n  = 0 , s = 0 , L = 0;
    47     cin >> n >> s;
    48     for(int i = 1;i<=n;i++)
    49     {
    50         cin >> L;
    51         l[L]++;
    52     }
    53     int counter = 0;
    54     if(s % 2)
    55     {
    56         int right = 0;
    57         for(ll i = s/2;i>=1;i--)
    58         {
    59             right += l[s-i] +l[i] -1;
    60             counter += l[i] * right -l[i]*(l[i]-1)/2;
    61             right += 1;
    62         }
    63     }
    64     else
    65     {
    66         if(l[s/2] > 1)
    67             counter += l[s/2]*(l[s/2]-1)/2;
    68         int right = l[s/2];
    69         for(ll i = s/2-1;i>=1;i--)
    70         {
    71             right += l[s-i] +l[i] -1;
    72             counter += l[i] * right -l[i]*(l[i]-1)/2;
    73             //cout<<i<<' '<<right<<' '<<counter<<endl;
    74             right += 1;
    75         }
    76     }
    77     cout << counter << endl;
    78     return 0;
    79 }

    队友用二分的做法 时间复杂度O(n*logn)

    甚至很迷的是这道题暴力居然都过了 适当优化的暴力做法

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4  
     5 using namespace std;
     6  
     7 const int N = 3e5;
     8 int a[N], b[1000010] = {0};
     9 long long s[1000010];
    10 int main()
    11 {
    12     int n, k, m = 0;
    13     cin>>n>>k;
    14     for(int i = 0; i < n; i ++ ) {
    15         scanf("%d", &a[i]);
    16         m = max(m, a[i]);
    17         b[a[i]]++;
    18     }//读入
    19     sort(a,a+n);
    20     int half = k / 2;
    21     int count = 0;
    22     for(int i = 0; i < n; i ++ ) {
    23         if(a[i] <= half) count ++;
    24         else break;
    25     }
    26     long long ans = count * (count - 1) / 2;
    27     s[0] = 0;
    28     for(int i = 1; i <= k; i ++ ) s[i] = s[i - 1] + b[i];
    29     for(int i = 0; a[i] < half; i += b[a[i]] ){
    30         long long  cnt = s[k - a[i]] - s[half];
    31         ans += cnt * b[a[i]];
    32     }
    33     if(k%2 != 0) ans += b[half] * b[half + 1];
    34     //ans += b[half] * (b[half] - 1) / 2;
    35     printf("%lld",ans);
    36     return 0;
    37 }

    作者:YukiRinLL

    出处:YukiRinLL的博客--https://www.cnblogs.com/SutsuharaYuki/

    您的支持是对博主最大的鼓励,感谢您的认真阅读。

    本文版权归作者所有,欢迎转载,但请保留该声明。

  • 相关阅读:
    C# -- 使用缓冲区进行文件下载操作
    C# -- 使用ODBC连接数据库
    C# -- Quartz.Net入门案例
    C# -- LinkedList的使用
    ASP.NET -- 获取浏览器信息
    Windows -- 从注册表删除IE浏览器加载项
    C# -- FTP上传下载
    C# -- 使用Ping检查网络是否正常
    WinForm -- 为TextBox文本框添加鼠标右键菜单
    C# -- 使用Parallel并行执行任务
  • 原文地址:https://www.cnblogs.com/SutsuharaYuki/p/11274979.html
Copyright © 2011-2022 走看看