cugb1220 兩個數組乘積第k大數--二分--2

 

http://acm.cugb.edu.cn/JudgeOnline/showproblem?problem_id=1220 

 

 

題意:有兩個數組a和b元素個數都有n(10000)個,且均爲正整數。。。求a[]*b[]所生成的c[]數組的第k大數。。

 

 

分析:二分求一個值v,這個值是最末尾一個c的元素中>=v的個數>=k。。。然後掃描a數組,二分b數組得到>=v的元素個數。。。

其實二分b數組還可以省略。。。因爲a和b數組都是排序了的,那麼對a中的元素往後掃,b中元素往後掃就可以得到結果了。。。。

 

二分還是要寫死我啊。。。。。

 

 

代碼:

一個二分。。100+ms。。難得的rank1啊啊啊。。

#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;

const int N=10010;
int n, k, a[N], b[N], flag;

int cal(int num)
{
	int i, j, k, ans, tmp;
	if(a[n-1]*b[n-1]<=num)
		return 0;
	j = n-1;
	ans = 0;
	for(i=0; i<n; i++)
	{
		for(; j>=0 && a[i]*b[j]>num; j--);
		ans += n-1-j;
	}
	return ans;
}

int bs() 
{
	int i, l, r, mid, ans, tmp;
	l=1, r=a[n-1]*b[n-1];
	while(l<=r)
	{
		flag = 0;
		mid = (l+r)>>1;
		tmp = cal(mid);
		if(tmp>=k)
			l = mid+1;
		else
			r = mid-1;
	}
	//r爲最後一個滿足比r大的個數>=k的值,所以r+1即爲所求。。。
	return r+1;
}

int main()
{
	int i, j, cas;
	scanf("%d", &cas);
	while(cas--)
	{
		scanf("%d%d", &n, &k);
		for(i=0; i<n; i++)
			scanf("%d", &a[i]);
		for(i=0; i<n; i++)
			scanf("%d", &b[i]);
		sort(a, a+n);
		sort(b, b+n);
		printf("%d\n", bs());
	}

	return 0;
}


 

 

兩個二分。。300+ms

#include <stdio.h>
#include <algorithm>
#include <cmath>
#include <iostream>
using namespace std;

const int N=10010;
int n, k, a[N], b[N], flag;

int bs1(int i, int num) //統計和a[i]相乘>num的總個數
{
	int l, r, mid;
	l=0, r=n-1;
	while(l<=r)
	{
		mid = (l+r)>>1;
		if(a[i]*b[mid]<=num)
			l = mid+1;
		else
			r = mid-1;
	}
	//r爲乘積<=num的最後一個位置
	return n-1-r; //乘積>num的總個數
}

int bs() 
{
	int i, l, r, mid, ans, tmp;
	l=1, r=a[n-1]*b[n-1];
	while(l<=r)
	{
		flag = 0;
		mid = (l+r)>>1;
		tmp = 0;
		for(i=0; i<n; i++) //對a掃描,二分b
			tmp += bs1(i, mid);
		if(tmp>=k)
			l = mid+1;
		else
			r = mid-1;
	}
	//r爲最後一個滿足比r大的個數>=k的值,所以r+1即爲所求。。。
	return r+1;
}

int main()
{
	int i, j, cas;
	scanf("%d", &cas);
	while(cas--)
	{
		scanf("%d%d", &n, &k);
		for(i=0; i<n; i++)
			scanf("%d", &a[i]);
		for(i=0; i<n; i++)
			scanf("%d", &b[i]);
		sort(a, a+n);
		sort(b, b+n);
		printf("%d\n", bs());
	}

	return 0;
}


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章