062:热血格斗场
总时间限制: 1000ms 内存限制: 65536kB
描述:
为了迎接08年的奥运会,让大家更加了解各种格斗运动,facer新开了一家热血格斗场。格斗场实行会员制,但是新来的会员不需要交入会费,而只要同一名老会员打一场表演赛,证明自己的实力。
我们假设格斗的实力可以用一个正整数表示,成为实力值。另外,每个人都有一个唯一的id,也是一个正整数。为了使得比赛更好看,每一个新队员都会选择与他实力最为接近的人比赛,即比赛双方的实力值之差的绝对值越小越好,如果有两个人的实力值与他差别相同,则他会选择比他弱的那个(显然,虐人必被虐好)。
不幸的是,Facer一不小心把比赛记录弄丢了,但是他还保留着会员的注册记录。现在请你帮facer恢复比赛纪录,按照时间顺序依次输出每场比赛双方的id。
输入:
第一行一个数n(0 < n <=100000),表示格斗场新来的会员数(不包括facer)。以后n行每一行两个数,按照入会的时间给出会员的id和实力值。一开始,facer就算是会员,id为1,实力值1000000000。输入保证两人的实力值不同。
输出:
N行,每行两个数,为每场比赛双方的id,新手的id写在前面。
样例输入:
3 2 1 3 3 4 2
样例输出:
2 1 3 2 4 2
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
struct Peo{
int id;
int force;
};
struct Rule{
bool operator()(const Peo & p1, const Peo & p2)const {
return p1.force > p2.force;
}
};
int main(){
multiset<Peo, Rule> st;
multiset<Peo, Rule>::iterator p, a, b;
Peo peo;
peo.id = 1;
peo.force = 1000000000;
st.insert(peo);
int n, x, y;
cin >> n;
for(int i = 1; i <= n; ++i){
cin >> peo.id >> peo.force;
st.insert(peo);
for(p = st.begin(); p != st.end(); ++p)
if(p->force == peo.force)
break;
a = p;
b = p;
a--;
b++;
if(b == st.end())
cout << p->id << ' ' << a->id << endl;
else{
x = a->force - peo.force;
y = peo.force - b->force;
if(y <= x)
cout << p->id << ' ' << b->id << endl;
else
cout << p->id << ' ' << a->id << endl;
}
}
return 0;
}
超时原因:中间的查找直接遍历了。
Accepted代码:
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
struct Peo{
int id;
int force;
};
struct Rule{
bool operator()(const Peo & p1, const Peo & p2)const {
return p1.force > p2.force;
}
};
int main(){
multiset<Peo, Rule> st;
multiset<Peo, Rule>::iterator p, a, b;
Peo peo;
peo.id = 1;
peo.force = 1000000000;
st.insert(peo);
int n, x, y;
cin >> n;
for(int i = 1; i <= n; ++i){
cin >> peo.id >> peo.force;
st.insert(peo);
p = st.lower_bound(peo);//二分查找下限
a = p;
b = p;
a--;
b++;
if(b == st.end())
cout << p->id << ' ' << a->id << endl;
else{
x = a->force - peo.force;
y = peo.force - b->force;
if(y <= x)
cout << p->id << ' ' << b->id << endl;
else
cout << p->id << ' ' << a->id << endl;
}
}
return 0;
}
改良地方:将上面的遍历查找改为了直接用lower_bound二分查找下线。
063:冷血格斗场
总时间限制: 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
#include <iostream>
#include <set>
#include <algorithm>
using namespace std;
struct Peo{
int id;
int f;
};
struct Rule{
bool operator()(const Peo & p1, const Peo & p2) const {
if(p1.f == p2.f)
return p1.id > p2.id;
else
return p1.f > p2.f;
}
};
typedef multiset<Peo, Rule> ST;
int main(){
ST st;
Peo p;
ST::iterator q, a, b, a1, b1;
p.id = 1;
p.f = 1000000000;
st.insert(p);
int n, x, y;
cin >> n;
for(int i = 1; i <= n; ++i){
cin >> p.id >> p.f;
st.insert(p);
q = st.lower_bound(p);
a = q;
b = q;
a--;
b++;
if(b == st.end()){//p是最菜的
cout << q->id << ' ' << a->id << endl;
}
else{//还有人比p菜
x = a->f - q->f;
y = q->f - b->f;
if(x < y)
cout << q->id << ' ' << a->id << endl;
else if(y < x){
b1 = b;
while(b1->f == b->f && b != st.end())
b1++;
b1--;
cout << q->id << ' ' << b1->id << endl;
}
else{//a->f == q->f == b->f || x == y
b1 = b;
while(b1->f == b->f && b != st.end())
b1++;
b1--;
if(a->id < b1->id)
cout << q->id << ' ' << a->id << endl;
else
cout << q->id << ' ' << b1->id << endl;
}
}
}
return 0;
}
这边用的是multiset,如果有大佬的话可以帮我改进改进。
Accepted代码:
#include <iostream>
#include <map>
#include <algorithm>
#include <cmath>
using namespace std;
typedef map<int, int> MP;
int main(){
MP mp;
MP::iterator i, j;
mp[1000000000] = 1;
int n, id, power, x, y;
cin >> n;
while(n--){
cin >> id >> power;
i = mp.lower_bound(power);
if(i == mp.end()){//没人比他还厉害
i--;
cout << id << ' ' << i->second << endl;
mp[power] = id;
}
else{
if(i->first == power){
cout << id << ' ' << i->second << endl;
if(id < i->second)
mp[power] = id;
}
else{
if(i != mp.begin()){
j = i;
j--;
}
else{
j = i;
}
x = abs(power - j->first);
y = abs(i->first - power);
if(x > y){
cout << id << ' ' << i->second << endl;
}
else if(y > x){
cout << id << ' ' << j->second << endl;
}
else{//x == y
if(j->second > i->second)
cout << id << ' ' << i->second << endl;
else
cout << id << ' ' << j->second << endl;
}
mp[power] = id;
}
}
}
return 0;
}