SWERC'2016 B 想法

BribingEve

Eve works at a magazine that does productreviews and publishes recommendations to consumers. They are working on a newmobile phones review and have decided on two reproducible tests that score eachdevice’s battery lifetime and performance using an integer between 1 and 1000.

These twoscores, x1 and x2, are thencombined with a weights vector w =[w1,w2] to produce an overallscore:

s = w1x1 + w2x2 .

The nal review ranking is then obtained bysorting the products by decreasing order of s.Additionally, when multiple products get exactly the same score, Eve decideshow to order them.

Maria (a fake name to mask her identity)tried to bribe Eve to tweak the results to get her product higher on the list.Eve argued that she was not able to tamper the evaluation of each test, butMaria suggested to tweak the weights w used when computingthe overall score. The weights w must benon-negative and at least one of them must be positive, but the values aredecided by Eve.

Eve isthinking whether to modify the weights in Maria’s benet or not, and asked youto determine what are the best and worst possible ranking positions for Maria’sproduct.

Task

Given a listof all products scores in battery and performance [x1,x2] tests,nd out what are the best and worst positions in the ranking that can be givento Maria’s product when the weights [w1,w2] and the order for tiedproducts are left for Eve to decide.

Input

The rst linehas the number N of products beingcompared. N lines follow, eachcontaining two integers x1 and x2 indicating aproduct’s score in the battery and performance tests. Maria’s product is therst on the list.

Constraints

1≤ N ≤ 100000      Number of products

1≤ x1,x2 ≤ 1000       Performance of a product in the tests

B     B

Output

The outputconsists of two numbers A and B, indicating the best and worst possible positions that Maria’sproduct can get on the ranking given Eve’s ability to modify the weights andordering in case of a tie.

Sample Input

5

7 7

11 10

8 5

1 1

12 12

Sample Output

3 4


题意:给你n组数  定义分数z=w1*x+w2*y  w1>=0  w2>=0  但是w1和w2不能同时为0  求第一组数最好的排名和最差的排名


题解:题目很坑  因为当分数相同时  你可以手动调排名的

假设 w1=0 w2>0  我们扫一遍可以得到max和min

同理当 w2=0 w1>0  我们扫一遍更新max和min

然后就是w2>0 w1>0

我们先让其他组的数减去第一组  我们就能得到x y的系数

所以让排名靠前就是 w1*x+w2*y<0

当x>0 y>0时  那不管w1 w2取何值  都是比第一组数大的

同理x<0 y<0  都比第一组数小

当 x=0 y=0 时  我们根据需求把他往第一组数前面或者后面放

当x=0 y!=0 时  y>0 就比第一组数大  同理 x!=0 y=0

当x>0 y<0时  w2/w1> -x/y  当x<0 y>0时  w2/w1<-x/y

我们可以把-x/y分别存到两个数组里  一个代表x>0 y<0  另一个代表x<0 y>0

然后对于每个数for过去  更新ans即可

ps:这题的逻辑性很强  所以细节很复杂


#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define eps 1e-8
struct node{
	int x,y;
}e[100005];
double e1[100005],e2[100005],es[100005];
int cnt1,cnt2,cnt;
int main(){
	int n,i,j,now=0,yz=0,yf=0,xz=0,xf=0,qz=0,qf=0,xff=0,yff=0;
	scanf("%d",&n);
	scanf("%d%d",&e[1].x,&e[1].y);
	for(i=2;i<=n;i++){
		scanf("%d%d",&e[i].x,&e[i].y);
		e[i].x-=e[1].x;
		e[i].y-=e[1].y;
		if(e[i].x==0&&e[i].y==0){
			now++;
			continue;
		}
		if(e[i].y>0)yz++;
		else if(e[i].y==0)yf++;
		else yff++;
		if(e[i].x>0)xz++;
		else if(e[i].x==0)xf++;
		else xff++;
		if(e[i].x==0||e[i].y==0){
			continue;
		}
		else{
			if(e[i].x>0&&e[i].y>0)qz++;
			else if(e[i].x<0&&e[i].y<0)qf++;
			else if(e[i].x>0&&e[i].y<0)e1[++cnt1]=(double)e[i].x/e[i].y*-1,es[++cnt]=e1[cnt1];
			else e2[++cnt2]=(double)e[i].x/e[i].y*-1,es[++cnt]=e2[cnt2];
		}
	}
	int ans1=min(1+yz,1+xz),ans2=max(1+yz+yf,1+xz+xf)+now;
	for(i=2;i<=n;i++){
		if(e[i].x==0||e[i].y==0)continue;
		if(e[i].y>0)yz--;
		else if(e[i].y==0)yf--;
		else yff--;
		if(e[i].x>0)xz--;
		else if(e[i].x==0)xf--;
		else xff--;
	}
	sort(e1+1,e1+1+cnt1);
	sort(e2+1,e2+1+cnt2);
	sort(es+1,es+1+cnt);
	int now1=qz,now2=now+qz;
	int s1=0,s2=0;
	for(i=1;i<=cnt;i++){
		if(fabs(es[i]-e1[s1+1])<eps&&fabs(es[i]-e2[s2+1])<eps){
			int k1=0,k2=0,s3=s1,s4=s2;
			while(fabs(es[i]-e1[s1+1])<eps&&fabs(es[i]-e1[s3+1])<eps){
				k1++;
				i++;
				s1++;
			}
			while(fabs(es[i]-e2[s2+1])<eps&&fabs(es[i]-e2[s4+1])<eps){
				k2++;
				i++;
				s2++;
			}
			i--;
			ans1=min(ans1,1+now1+cnt1-s1+s4+yz+xz);
			ans2=max(ans2,1+now2+cnt1-s3+s2+yz+xz);
			continue;
		}
		if(fabs(es[i]-e1[s1+1])<eps){
			int k1=0,s3=s1,s4=s2;
			while(fabs(es[i]-e1[s1+1])<eps&&fabs(es[i]-e1[s3+1])<eps){
				k1++;
				i++;
				s1++;
			}
			i--;
			ans1=min(ans1,1+now1+cnt1-s1+s4+yz+xz);
			ans2=max(ans2,1+now2+cnt1-s3+s2+yz+xz);
		}
		else{
			int k2=0,s3=s1,s4=s2;
			while(fabs(es[i]-e2[s2+1])<eps&&fabs(es[i]-e2[s4+1])<eps){
				k2++;
				i++;
				s2++;
			}
			i--;
			ans1=min(ans1,1+now1+cnt1-s1+s4+yz+xz);
			ans2=max(ans2,1+now2+cnt1-s3+s2+yz+xz);
		}
	}
	printf("%d %d\n",ans1,ans2);
	return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值