2013年北京大学夏令营及保研考试

编程入门 行业动态 更新时间:2024-10-26 18:27:25

2013年<a href=https://www.elefans.com/category/jswz/34/1751377.html style=北京大学夏令营及保研考试"/>

2013年北京大学夏令营及保研考试

2013年北京大学夏令营及保研考试 -B题


(OPENJUDGE)NOI3344:冷血格斗场 /


总时间限制: 1000ms 内存限制: 65536kB 


描述

为了迎接08年的奥运会,让大家更加了解各种格斗运动,facer新开了一家冷血格斗场。格斗场实行会员制,但是新来的会员不需要交入会费,而只要同一名老会员打一场表演赛,证明自己的实力。


我们假设格斗的实力可以用一个正整数表示,成为实力值,两人的实力值可以相同。另外,每个人都有一个唯一的id,也是一个正整数。为了使得比赛更好看,每一个新队员都会选择与他实力最为接近的人比赛,即比赛双方的实力值之差的绝对值越小越好,如果有多个人的实力值与他差别相同,则他会选择id最小的那个


不幸的是,Facer一不小心把比赛记录弄丢了,但是他还保留着会员的注册记录。现在请你帮facer恢复比赛纪录,按照时间顺序依次输出每场比赛双方的id。

输入
第一行一个数n(0 < n <=100000),表示格斗场新来的会员数(不包括facer)。以后n行每一行两个数,按照入会的时间给出会员的id和实力值。一开始,facer就算是会员,id为1,实力值1000000000。输入保证两人的实力值不同。

输出
N行,每行两个数,为每场比赛双方的id,新手的id写在前面。

样例输入
3
2 3
3 1
4 2
样例输出
2 1
3 2
4 2
解题思路   使用map实现从实力值到id的映射,以下代码的问题是并没有AC,但测试数据却通过,百思不得其解; 代码
#include <iostream>
#include <map>using namespace std;
int main() {map<long long,int>mp;//实力值到id的映射map<long long,int>::iterator it,it1,it2;int n;mp[1000000000]=1;cin>>n;int id,cap;//id和实力值for(int i=0;i<n;i++){cin>>id>>cap;mp[cap]=id;/*for(it=mp.begin();it!=mp.end();it++){if(it->first == cap){break;}}*/it=mp.find(cap);//find()是根据key查找valueit1=it2=it;if(it==mp.begin()){it1++;cout<<id<<" "<<it1->second<<endl;//如果新加会员在map首部,下一个即为挑战者continue;}else{//map中it的前一个会员it1--;int cap1=it1->first;int id1=it1->second;//map中it的后一个会员it2++;int cap2=it2->first;int id2=it2->second;if(abs(cap-cap1)<abs(cap2-cap)){cout<<id<<" "<<id1<<endl;//如果有两个人的实力值与他差别相同,实力弱的为下一个挑战者}else if(abs(cap-cap1)>abs(cap2-cap)){cout<<id<<" "<<id2<<endl;}else if(abs(cap-cap1)==abs(cap2-cap)){cout<<id<<" "<<min(id1,id2)<<endl;}}}return 0;
}
下面代码转载自 ,经测试确实AC
#include <iostream>
#include<map>
using namespace std;
map<int,int>mp;  //运用映射建立存储结构map<int,int>::iterator it;
int n;int main()
{mp[1000000000]=1;//首先是facer,编号为1,能力值为1000000000//freopen("in.txt","r",stdin);cin>>n;for(int i=1;i<=n;i++){int id,cap;scanf("%d%d",&id,&cap);it=mp.lower_bound(cap);//查找能力值不小于目前即将加入的新成员的元素if(it==mp.end())    it--;//迭代器指向映射的最后一个元素后面的地址,说明没有找到,没有人的实力强新人的能力,那么就找到最后一个元素,他的能力值一定是最接近新人的int t=abs(it->first-cap);int idx=it->second;if(it!=mp.begin())//先判断,如果it就指向映射的第一个元素就不执行,否则会访问违规地址{it--;if(t>abs(it->first-cap) || (t==abs(it->first-cap) && it->second<idx))//能力差值相同,去找id小的{t=abs(it->first-cap);idx=it->second;}}printf("%d %d\n",id,idx);it=mp.find(cap);if(it->second>id || it==mp.end())mp[cap]=id;//因为在加入新成员时,与任意成员进行比赛时都要选择id号最小的,那么一旦在相同的能力值上有了一个人且其id较小的老成员,id较大的新成员就一定不会再进行比赛(优先选择id小的)}return 0;
}





更多推荐

2013年北京大学夏令营及保研考试

本文发布于:2024-03-10 12:13:54,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1727937.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:北京大学   夏令营   考试   保研

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!