hdu4585(STL的map应用)

Shaolin
Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d & %I64u
Submit Status

Description
Shaolin temple is very famous for its Kongfu monks.A lot of young men go to Shaolin temple every year, trying to be a monk there. The master of Shaolin evaluates a young man mainly by his talent on understanding the Buddism scripture, but fighting skill is also taken into account.
When a young man passes all the tests and is declared a new monk of Shaolin, there will be a fight , as a part of the welcome party. Every monk has an unique id and a unique fighting grade, which are all integers. The new monk must fight with a old monk whose fighting grade is closest to his fighting grade. If there are two old monks satisfying that condition, the new monk will take the one whose fighting grade is less than his.
The master is the first monk in Shaolin, his id is 1,and his fighting grade is 1,000,000,000.He just lost the fighting records. But he still remembers who joined Shaolin earlier, who joined later. Please recover the fighting records for him.


Input
There are several test cases.
In each test case:
The first line is a integer n (0 <n <=100,000),meaning the number of monks who joined Shaolin after the master did.(The master is not included).Then n lines follow. Each line has two integer k and g, meaning a monk's id and his fighting grade.( 0<= k ,g<=5,000,000)
The monks are listed by ascending order of jointing time.In other words, monks who joined Shaolin earlier come first.
The input ends with n = 0.


Output
A fight can be described as two ids of the monks who make that fight. For each test case, output all fights by the ascending order of happening time. Each fight in a line. For each fight, print the new monk's id first ,then the old monk's id.


Sample Input

2 1 

3 3

4 2 

0




Sample Output

2 1 

3 2 

4 2



解题思路:

纯STL的应用·······叉哥·······这叫签到题!!!现学STL!!!

题意是给个n,接下来n行输入,每行两个数分别代表僧侣的id和战斗力,并且僧侣的id都是按升序输入的

(等同于他们的来挑战的顺序),最后要求输出n行当前僧侣来的时候,他和哪个僧侣战斗。战斗的原则

是他会在已经来到的僧侣中选一个战斗力跟他相近的僧侣进行战斗,我们要关注的就这个老僧侣的id,如

果出现两个与他战斗力差值相同的情况下,我们输出id小的那个。

分析完题意,我可sxk大牛就在想怎么搞,普通的O(n^2)算法一定超时,因为n达到1e5,那怎么优化呢···

··常规思路想不出来怎么优化········百度了一下发现STL的map可以实现快速的查找和插入,其实这道题

最主要费时间的地方不就是查找和插入嘛·······于是现学STL········再次重申·······叉哥说这是签到题~~~orz

map映射这个以前写过一次,那次是string和int的映射,这次改成int到int的映射。map查找时需要记录

一个key值,即map[key] = data,这里我们把key值设为僧侣的战斗力,把id设为保存的数据,也就是

map[grade] = id。

新技能·····map除了映射,还有一个迭代器的功能,map<int , int>::iterator,感觉类似于变量交换时中间

变量的作用·····顺便一提,存入map中后,他会自动按key值排好序。精彩的地方来了,先用迭代器保存

当前僧侣在map中grade对应的id。如果他是第一个的话,那么输出他后一位的id。这里迭代器的first代

表关键字(key值),second代表data。否则的话我们则另外在开一个等同于temp的迭代器,看它前一

个后一个的key值分别和当前grade的差值,取差值小的那个的data。

最后······叉哥说这是签到题!!!!

附:叉哥牛XX·······orz·······




完整代码:

#include <functional>
#include <algorithm>
#include <iostream>
#include <fstream>
#include <sstream>
#include <iomanip>
#include <numeric>
#include <cstring>
#include <climits>
#include <cassert>
#include <complex>
#include <cstdio>
#include <string>
#include <vector>
#include <bitset>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <list>
#include <set>
#include <map>
using namespace std;

#pragma comment(linker, "/STACK:102400000,102400000")

typedef long long LL;
typedef double DB;
typedef unsigned uint;
typedef unsigned long long uLL;

/** Constant List .. **/ //{

const int MOD = int(1e9)+7;
const int INF = 0x3f3f3f3f;
const LL INFF = 0x3f3f3f3f3f3f3f3fLL;
const DB EPS = 1e-9;
const DB OO = 1e20;
const DB PI = acos(-1.0); //M_PI;

map<int , int> m;
int res;
int main()
{
    #ifdef DoubleQ
    freopen("in.txt","r",stdin);
    #endif
    int n;
    while(~scanf("%d",&n) && n)
    {
        m[1000000000] = 1;
        int grade , id;
        for(int i = 0 ; i < n ; i ++)
        {
            scanf("%d%d",&id , &grade);
            m[grade] = id;
            map<int , int> :: iterator temp = m.find(grade);
            if(temp == m.begin())
                res = (++temp)->second;
            else
            {
                map<int , int> :: iterator temp2 = temp;
                if( abs((++temp)->first - grade) >= abs((--temp2)->first - grade) )
                    res = temp2->second;
                else
                    res = temp->second;
            }
            printf("%d %d\n", id , res);
        }
        m.clear();
    }
}





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值