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


 Time Limit Exceeded代码:

#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


Time Limit Exceeded代码:

#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;
}