L1-056 猜数字
题干:
一群人坐在一起,每人猜一个 100 以内的数,谁的数字最接近大家平均数的一半就赢。本题就要求你找出其中的赢家。
输入格式:
输入在第一行给出一个正整数N(≤104)。随后 N 行,每行给出一个玩家的名字(由不超过8个英文字母组成的字符串)和其猜的正整数(≤ 100)。
输出格式:
在一行中顺序输出:大家平均数的一半(只输出整数部分)、赢家的名字,其间以空格分隔。题目保证赢家是唯一的。
输入样例:
7
Bob 35
Amy 28
James 98
Alice 11
Jack 45
Smith 33
Chris 62
输出样例:
22 Amy
二分知识:
①在单增序列a中查找>=x的数中最小的一个(即x或x的后继,类似ceil())
代码:
while(l<r){
int mid=(l+r)>>1;
if(a[mid]>=x) r=mid;//大于等于
else l=mid+1;
}//总结:求大,中大,中等右(要求出大,mid大于等于未知,mid等于右边)
return a[l];
注意: 右移运算向下取整,整数除法向零取整
②在单增序列a中查找<=x的数中最大的一个(即x或x的前驱,类似floor())
代码:
while(l<r){
int mid=(l+r+1)>>1;
if(a[mid]<=x) l=mid;//小于等于
else r=mid-1;
}//总结:求小,中小,中等左(要求出小,mid小于等于未知,mid等于左边)
return a[l];
本题代码:
//ios::sync_with_stdio(false);
#include<bits/stdc++.h>
#define LL long long
#define fo(i,a,b) for(int i=a;i<b;i++)
#define foo(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
struct st{char s[10]; int b; } a[10000];
bool cmp(st st1,st st2){return st1.b<st2.b;}
int main(){
ios::sync_with_stdio(false);
memset(a,0,sizeof(a));
int n;cin>>n;
double sum=0;
fo(i,0,n){
cin>>a[i].s>>a[i].b;
sum+=a[i].b;
}
sum/=2*n;
int t=(int)sum;//经测试cout<<(int)(sum/2)也没错
cout<<t<<" ";
sort(a,a+n,cmp);//cout<<a[0].s<<a[0].b;检查过程
int l=0,r=n-1;
if(a[0].b>=sum){
cout<<a[0].s;
return 0;
}//特判
while(l<r){
int mid=(l+r)>>1;
if(a[mid].b>=t)r=mid;
else l=mid+1;
}//类似ceil()
if(a[l].b-t<t-a[l-1].b)cout<<a[l].s;
else cout<<a[l-1].s;
return 0;
}