1. 程式人生 > >【分治演算法】化妝晚會

【分治演算法】化妝晚會

題目描述

萬聖節又到了!Farmer John打算帶他的奶牛去參加一個化裝晚會,但是,FJ只做了一套能容下兩頭總長不超過S(1 < = S < = 1,000,000)的牛的恐怖服裝。FJ養了N(2 < = N < = 50,000)頭按1…N順序編號的奶牛,編號為i的奶牛的長度為L_i(1 < = L_i < = 1,000,000)。如果兩頭奶牛的總長度不超過S,那麼她們就能穿下這套服裝。 FJ想知道,如果他想選擇兩頭不同的奶牛來穿這套衣服,一共有多少種滿足條件的方案。

輸入

輸入檔案的第1行是 2個用空格隔開的整數:N 和 S, 第2…N+1行每行一個整數:L_i

輸出

1行: 輸出1個整數,表示FJ可選擇的所有方案數。注意奶牛順序不同的兩種方案是被視為相同的

輸入樣例

4 6 3 5 2 1

輸出樣例

4

說明

輸出說明: 4種選擇分別為:奶牛1和奶牛3;奶牛1和奶牛4;奶牛2和奶牛4;奶牛3和 奶牛4。 【資料規模】 對於30%的資料,N<=10000; 對於100%的資料,N<=50000

分析

不因為順序而影響結果,因此排完序後就找到容不下的就break;但是要二分查詢

程式碼

#include<cstdio>
#include<algorithm>
using namespace std;
long long a[200010],s,n;
long long check(int b,int c)
{
    int low = b,hi = n+1;
	while(low+1 < hi)
	{
		int mid =(low + hi)/2;
		if(a[mid] <= c) low = mid;
		else hi = mid;
	}
   return low - b;
}
int main()
{
	long long i,ans=0,k;
	scanf("%d%d",&n,&s);
	for(i=1;i<=n;i++)
	{
		scanf("%d",&a[i]);
	}
	sort(a+1,a+n+1);
	a[0]=-1;
	a[n+1]=1000001;
	for(i=1;i<=n;i++)
	{
		k=a[i];
		ans=ans+check(i,s-a[i]);
	}
	printf("%d",ans);
	return 0;
}