• cqyz oj | 化装晚会 | 二分搜索 | 贪心


    Description

      万圣节又到了!FJ打算带他的奶牛去参加一个化装晚会,但是FJ只做了一套能容下两头总长不超过 S 的牛的恐怖服装。FJ养了 N 头按 1..N 顺序编号的奶牛,编号为 i 的奶牛的长度为 Li。如果两头奶牛的总长度不超过 S,那么她们就能穿下这套服装。
      FJ想知道,如果他想选择两头不同的奶牛来穿这套衣服,一共有多少种满足条件的方案。

    Input

      第 1 行是 2 个用空格隔开的整数 N 和 S;  接下来有 n 行,每行包含一个整数 L_i,表示奶牛的身长为。

    Output

      仅一行一个整数,表示FJ可选择的所有方案数。注意奶牛顺序不同的两种方案是被视为相同的

    Sample Input 1

    4 6
    3 5 2 1

    Sample Output 1

    4

    Hint

    2 <= N <= 1,000,0001 <= S <= 2,000,000,0001 <= L_i <= 2,000,000,000


    首先可以注意到数据量很大,所以先放弃(O(n^2))的暴力枚举法。

    首先想到可以排序后对每头牛i二分搜索和它满足条件的第二头牛j,,则比j长度小的牛也都满足条件,枚举第一头牛+二分搜索,复杂度(O(nlogn))

    如果从大向小枚举i,那么其实没必要每次重新二分找j,因为满足前一头牛的j一定满足当前的牛(想一想,为什么)。所以j可以按从小到大的顺序移动。复杂度降为(O(n))
    细节见代码:

    #include <iostream>
    #include <cstdlib>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #include <queue>
    #include <stack>
    #include <vector>
    #include <set>
    #include <map>
    #include <iomanip>
    #define inf 0x7f7f7f7f
    using namespace std;
    int n,s,cow[1000005];
    long long ans=0;
    int readd(int &x) //快读int 
    {
    	char ch;
    	x=0;
    	while(!isdigit(ch)) ch=getchar();
    	while(isdigit(ch))
    	{
    		x=x*10+ch-'0';
    		ch=getchar();
    	}
    	return 0;
    }
    int main()
    {
    	scanf("%d%d",&n,&s);
    	for(int i=1;i<=n;i++) readd(cow[i]);
    	sort(cow+1,cow+1+n);
    	int i=1,j=n;
    	for(j=n;j>=1;j--)
    	{
    		while(i<=n && cow[j]+cow[i]<=s) i++;
    		if(j>=i)ans+=i-1;
    		else	ans+=i-2;
    	}
    	cout<<ans/2;
    }
    
  • 相关阅读:
    Photoshop
    你会为了钱出售自己的个人资料吗?
    [ElasticSearch] 空间搜索 (一)
    hdu1584 A strange lift (电梯最短路径问题)
    Android API Guides---OpenGL ES
    Qt 推断一个IP地址是否有效
    bzoj1670【Usaco2006 Oct】Building the Moat 护城河的挖掘
    集成学习1-Boosting
    微信开发模式之自己定义菜单实现
    人件札记:开放式的办公室环境
  • 原文地址:https://www.cnblogs.com/de-compass/p/11252901.html
Copyright © 2020-2023  润新知