codeforces #412

A. Is it rated?
题目给出n对数 分别为分数变化前后的数 以递减输入 询问是否codefoces在一场比赛结束后变分了。
如果这一对数全部相同,说明不知道变没变化
如果左右不同,说明已经改变了
如果一个低分有更好的排名 than 高分有低的排名说明排名没改变。


B. T-Shirt Hunt
给3个数字 p x y x>=y
分别表示位子p 目前分数x  最低要得到衬衫条件y
可以通过成功hack 或者 不成功的hack 得到或者失去分数
问最低需要hack成功几次可以得到衬衫
得到衬衫的位置为   s是指目前的分数
i := (s div 50) mod 475
repeat 25 times:
    i := (i * 96 + 42) mod 475
    print (26 + i)
从x开始每次-50的到>=y,枚举判断是否有输出的情况包括有位置p,如果有那么一次成功的hack都不需要。
如果没有,就从50开始hack向上加,直到这个公式的输出有符合位置,那么加的(分数+50)/100就是最小hack成功数。


C. Success Rate
给4个数字 x y p q
问x为cf的提交成功数 y为cf的提交数,问最少还需要提交几次可以达到比例p/q
当p==q的时候,为百分百提交成功,那么x必须等于y 否者输出-1
当p==0的时候,为肯定提交不成功,那么x也必须等于0,否则输出-1
由其为p/q的比例,那么最终化成的结果y必定为q的倍数,那么可以二分满足比例达到p/q条件的最小值.
二分mid从(1-y)*q,也就是全部算提交成功.因为(y*q-y)+x/(y*q)=((q-1)+x/y)/q必定大于(q-1)/q
全部算提交不成功x/yq=(x/y)/q也必定小于p/q,那么提交的比例就是分别在p/q之间,那么就为合适的二分区间
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
const int maxn=1e5+7;
int main(){
	//freopen("in.txt","r",stdin);
	int i,j,k,f1,f2,f3,t1,t2,t3,sum1,sum2;
	int n,m;
	cin >> n;
	int x,y,p,q;
	for(i=1;i<=n;i++){
		cin >> x >> y >> p >> q;
		if((p==q&&x!=y)||(p==0&&x!=0)){
			cout << "-1" << endl;
			continue;
		}
		long long left1,right1,mid1;
		left1=1;right1=y;
		long long min1=1e9+7;
		while(right1>=left1){
			mid1=(right1+left1)/2;
			if(mid1*q>=y&&(mid1*q-y)+x>=p*mid1&&x<=p*mid1){
	//	cout << mid1*q << "    " << mid1*q-y+x <<"   ??"  <<p*mid1 <<"    " << x << endl; 	
				min1=min(min1,mid1);
				right1=mid1-1;
			}else{
				left1=mid1+1;
			}
		}
		cout << min1*q-y << endl;
	}
	return 0;
}


D. Dynamic Problem Scoring
第1个数n,表示有n个人
第1个人有无数个小号,其可以提交无数次题目(但ac的题只能提交他ac的题目)
问最小注册账号数通过调整参与人数来改变cf每个人得到的分数,使得1分数比2高
显然如果所有1提交比b慢的都算500分(除了-1),1比2快提交的1全部算3000分,
1的总分还没2高,那么1是不可能赢2。
暴力枚举小号个数,每个小号都提交失败(对于1做出比2块,以为了加高1比2多的分),
每个小号都提交成功(对于2作出比1块,为了降低2比1多的得分,前提是1做出来了)
观察数据范围发现如此枚举即可。

最后如果参加了许多小号使得已经全部改为想要的比例,还无法赢,就输出-1

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stack>
#include <vector>
#include <algorithm>
#include <set>
using namespace std;
const int maxn=1e5+7;
int k1[10],k2[10];
int k3[10];
int fun1(double x,double y,double t){ //表示参与x人,y人ac,t时间解决 
	if(t==-1)return 0;
	double t1=0;
	if(y/x>1.0/2){
		t1=500;
	}else if(y/x>1.0/4){
		t1=1000;
	}else if(y/x>1.0/8){
		t1=1500;
	}else if(y/x>1.0/16){
		t1=2000;
	}else if(y/x>1.0/32){
		t1=2500;
	}else{
		t1=3000;
	}
	t1=t1*(1-t*1.0/250);
	return t1;
}
int main(){
	//freopen("in.txt","r",stdin);
	int i,j,k,f1,f2,f3,t1,t2,t3,t4,t5,sum1,sum2;
	int n,m;
	cin >> n;
	int nn=n;
	memset(k3,0,sizeof(k3));
	for(i=1;i<=n;i++){
		cin >> t1 >> t2>> t3>> t4 >> t5;
		if(i==1){
		k1[1]=t1;k1[2]=t2;k1[3]=t3;k1[4]=t4;k1[5]=t5;
		}else if(i==2){
		k2[1]=t1;k2[2]=t2;k2[3]=t3;k2[4]=t4;k2[5]=t5;
		}
		if(t1!=-1)k3[1]++;
		if(t2!=-1)k3[2]++;
		if(t3!=-1)k3[3]++;
		if(t4!=-1)k3[4]++;
		if(t5!=-1)k3[5]++;
	}
	while(1){
		sum1=0;sum2=0;
		for(i=1;i<=5;i++){
			sum1+=fun1(n,k3[i],k1[i]);
			sum2+=fun1(n,k3[i],k2[i]);
	}
	if(sum1>sum2){
		cout << n-nn<< endl;return 0;
	}
		n++;
		for(i=1;i<=5;i++){
			if((k1[i]<k2[i]&&k1[i]!=-1)||(k2[i]==-1&&k1[i]!=-1)){
				; //成功人数	
			}else if(k1[i]!=-1){
				k3[i]++;
			}else{
				;
			}
		}
		if(n>120*32+7)break; //因为存在无法使其变成500的点,随着人数增加2的分数也不是500
		//所以可能存在之前判断可超过但最后超不过的情况 
	}
	cout << "-1" << endl;
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值