hdu 4938 Seeing People 排序+二分查找

Seeing People

Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 241    Accepted Submission(s): 61

Problem Description

There are two kinds of people.

If person i is the first kind of people, it locates at position (pi, 0) initially, starts moving at time ti with a constant velocity of (0, v1), and then sees every person sits at the line segment (xi, yi), (xi + wi, yi), include the two points, where (xi,
yi) is the position of person i at that time and wi is its vision.

If person i is the second kind of people, it locates at position (0, pi) initially, starts moving at time ti with a constant velocity of (v2, 0), and then sees every person sits at the line segment (xi, yi), (xi, yi + wi), include the two points, where (xi,
yi) is the position of person i at that time and wi is its vision.

Now given the position of people, please calculate the number of distinct people every person has finally seen.

Input

There are multiply test cases.

The first line contains an integer T(T<=10), indicates the number of cases.

For each test case, the first line contains three integers n, v1, v2(1<=n,v1,v2<=10^5), indicating the total number of two kinds of people, the speed of the first kind, and the speed of the second kind.

Then comes N lines, the i-th line contains four integers ai, ti, pi, wi (1<=ai<=2, 1<=ti,pi,wi<=10^5), describing a person, where ai is the type, ti is time the person starts moving, pi is the location and wi is the vision.

It is granted that for the same kind of people, all ti, pi are different.

Output

For each case, you should output "Case #k:" first, where k indicates the case number and counts from 1.

Then output N lines, each lines is an integer, indicates the number of distinct people the i-th person finally recorded.

Sample Input

1
2 1 1
1 1 1 1
2 2 2 1

Sample Output

Case #1:
1
1

Author

UESTC

Source

2014 Multi-University Training Contest 7

排序+二分查找,代码改了一下午,虽然花了很多时间,不过学到的东西很多

#include <cmath>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
using namespace std;
const int inf=1e9;
int v1,v2,n,T;
struct Node{
	long long t,p,w,kind,rank,cnt;
	double see_right,see_left;
	void init(int i)
	{
		double k=double (v2)/double(v1);
		cnt=0;
		rank=i;
		if(kind==1){
			see_left=p-t*v2;
			see_right=see_left+w;
		}
		else {
			see_left=p*k-t*v2;
			see_right=see_left+w*k;
		}
	}
	bool operator < (const Node& tem) const{
		return see_left < tem.see_left;
	}
}ans[100010];
double data1[100010],data2[100010];
bool cmp(Node a,Node b)
{
	return a.rank<b.rank;
}

void init ()
{
	scanf("%d %d %d ",&n,&v1,&v2);
	memset(data1,0,sizeof(data1));
	memset(data2,0,sizeof(data2));
	for(int i=0;i<n;i++)
	{
		scanf("%d %d %d %d",&ans[i].kind,&ans[i].t,&ans[i].p,&ans[i].w);
		ans[i].init(i);
	}
}
void slove()
{
	init();
	sort(ans,ans+n);
	int cnt1=0,cnt2=0;
	for(int i=0;i<n;i++)
	{
		if(ans[i].kind==1)
		{
			data1[cnt1++]=ans[i].see_left;
		}
		else {
			data2[cnt2++]=ans[i].see_left;
		}
	}
	data1[cnt1]=inf,data2[cnt2]=inf;
	for(int i=0;i<n;i++)
	{
		if(ans[i].kind==2){
			ans[i].cnt=upper_bound(data1,data1+cnt1+1,ans[i].see_right)-lower_bound(data1,data1+cnt1+1,ans[i].see_left);
		}
		else{
			ans[i].cnt=upper_bound(data2,data2+cnt2+1,ans[i].see_right)-lower_bound(data2,data2+cnt2+1,ans[i].see_left);

		}
	}
	sort(ans,ans+n,cmp);
	for(int i=0;i<n;i++)
	{
			printf("%d\n",ans[i].cnt);
	}
}
int main ()
{
	//freopen("1004.in","r",stdin);
	//freopen("data.out","w",stdout);
	int cas=0;
	scanf("%d",&T);
	while (T--)
	{

		printf("Case #%d:\n",++cas);
		slove();
	}
	return 0;
}

hdu 4938 Seeing People 排序+二分查找

时间: 2024-08-27 13:37:45

hdu 4938 Seeing People 排序+二分查找的相关文章

8.8 冒泡排序 选择排序 二分查找 递归使用

冒泡排序: #include <stdio.h> #include <stdlib.h> #include <time.h> #define N 100000 #define M 100000 void show_arr(int * a,int n) { int i; for(i = 0; i < n; i++) { printf("%d ",a[i]); } printf("\n"); } void init_arr(in

hdu 5199 Gunner (hash || 排序+二分)

题意:有n个不同高度的树排成一列,树上各有1只鸟. 然后m个询问,每次询问可以打掉h[i](1<=i<=m)高度的所有鸟,问m个询问中的各高度能打掉多少只鸟. 分析: 1.题目给了提示要 “快速读入”  咩~ 2.排序+二分 这里可以两次二分(lower_bound找下界,upper_bound找上界) 也可以合并+二分(合并相同的数字,记录次数) g++提交要用#include<stdio.h> 不要用#include<cstdio> 后者有效率问题,会 tle (⊙

uva 10763 Foreign Exchange(排序+二分查找)

这道题是我第一次算出来应该用什么复杂度写的题,或许是这一章刚介绍过,500000的数据必须用nlogn,所以我就 想到了二分,它的复杂度是logn,再对n个数据进行遍历,正好是nlogn,前两次TLE了,然后我就对我的做法没信心 了...看到一篇博客上说就应该这种方法,然后我就坚定的改自己的算法去了,哈哈,专注度没有达到五颗星,最多 三颗... 思路: 我用的是结构体保存的,先对每一对序列排序,然后对第二个元素在第一个元素中二分搜索,用到了 lower_bound,upper_bound,注释里

HDU 4614 线段树+二分查找

Vases and Flowers 题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=4614 Problem Description Alice is so popular that she can receive many flowers everyday. She has N vases numbered from 0 to N-1. When she receive some flowers, she will try to put them

I Count Two Three(打表+排序+二分查找)

I Count Two Three 二分查找用lower_bound 这道题用cin,cout会超时... AC代码: 1 /* */ 2 # include <iostream> 3 # include <cstring> 4 # include <string> 5 # include <cstdio> 6 # include <cmath> 7 # include <algorithm> 8 using namespace st

HDU 2446 Shell Pyramid(二分查找 数学)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2446 Problem Description In the 17th century, with thunderous noise, dense smoke and blazing fire, battles on the sea were just the same as those in the modern times. But at that time, the cannon ,were e

[FAFU 1266]STL排序+二分查找

http://acm.fafu.edu.cn/problem.php?id=1266 思路很容易理解: #include<cstdio> #include<algorithm> using namespace std; int num[1000000]; int main() { int n,m,a; while(~scanf("%d",&n)) { for(int i=0;i<n;++i) { scanf("%d",&

优化的直接插入排序(二分查找插入排序,希尔排序)

直接插入排序 (一)概念及实现 直接插入排序的原理:先将原序列分为有序区和无序区,然后再经过比较和后移操作将无序区元素插入到有序区中. 具体如下(实现为升序): 设数组为a[0…n]. 1.        将原序列分成有序区和无序区.a[0…i-1]为有序区,a[i…n] 为无序区.(i从1开始) 2.        从无序区中取出第一个元素,即a[i],在有序区序列中从后向前扫描. 3.        如果有序元素大于a[i],将有序元素后移到下一位置. 4.        重复步骤3,直到找

STL之二分查找:hdu 5178 ( BestCoder Round #31 1001 )

STL包含四种不同的二分查找算法,binary_search    lower_bound  upper_bound   equal_range.他们的作用域是已经排序好的的数组. ★binary_search试图在已排序的[first, last)中寻找元素value.如果找到它会返回true,否则返回false,它不返回查找位置. ★iterator lower_bound( const key_type &key ): 返回一个迭代器,指向键值>= key的第一个元素. ★iterat