CodeForces 659 B. Qualifying Contest(结构体排序的问题)

传送门

B. Qualifying Contest

time limit per test1 second

memory limit per test256 megabytes

inputstandard input

outputstandard output

Very soon Berland will hold a School Team Programming Olympiad. From each of the m Berland regions a team of two people is invited to participate in the olympiad. The qualifying contest to form teams was held and it was attended by n Berland students. There were at least two schoolboys participating from each of the m regions of Berland. The result of each of the participants of the qualifying competition is an integer score from 0 to 800 inclusive.

The team of each region is formed from two such members of the qualifying competition of the region, that none of them can be replaced by a schoolboy of the same region, not included in the team and who received a greater number of points. There may be a situation where a team of some region can not be formed uniquely, that is, there is more than one school team that meets the properties described above. In this case, the region needs to undertake an additional contest. The two teams in the region are considered to be different if there is at least one schoolboy who is included in one team and is not included in the other team. It is guaranteed that for each region at least two its representatives participated in the qualifying contest.

Your task is, given the results of the qualifying competition, to identify the team from each region, or to announce that in this region its formation requires additional contests.

Input

The first line of the input contains two integers n and m (2?≤?n?≤?100?000, 1?≤?m?≤?10?000, n?≥?2m) — the number of participants of the qualifying contest and the number of regions in Berland.

Next n lines contain the description of the participants of the qualifying contest in the following format: Surname (a string of length from 1 to 10 characters and consisting of large and small English letters), region number (integer from 1 to m) and the number of points scored by the participant (integer from 0 to 800, inclusive).

It is guaranteed that all surnames of all the participants are distinct and at least two people participated from each of the m regions. The surnames that only differ in letter cases, should be considered distinct.

Output

Print m lines. On the i-th line print the team of the i-th region — the surnames of the two team members in an arbitrary order, or a single character “?” (without the quotes) if you need to spend further qualifying contests in the region.

Examples

input

5 2

Ivanov 1 763

Andreev 2 800

Petrov 1 595

Sidorov 1 790

Semenov 2 503

output

Sidorov Ivanov

Andreev Semenov

input

5 2

Ivanov 1 800

Andreev 2 763

Petrov 1 800

Sidorov 1 800

Semenov 2 503

output

?

Andreev Semenov

Note

In the first sample region teams are uniquely determined.

In the second sample the team from region 2 is uniquely determined and the team from region 1 can have three teams: “Petrov”-“Sidorov”, “Ivanov”-“Sidorov”, “Ivanov” -“Petrov”, so it is impossible to determine a team uniquely.

题目大意:

就是给了n个名字,m个地方,然后我们需要每个地方中选取两个最大的分数,输出的是两个最大的分数的名字,如果第二和第三的分数是一样的,我们就输出’?’

解题思路:

这个题其实是一个水题,然后我们就是排一下序就行了,先把m个区域排好序,然后将分数从大到小排好序,然后就是判断一下就行了。注意的是可能不到2个人,那么也是输出’?’,还有一个小技巧就是把arr[n].id==-1,因为我们每次判断的是当前的id与它的前一个是不是相同,所以最后要将n那个赋为-1,有两种方法都可以参考一下:

第一个:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
using namespace std;
const int MAXN = 1e5+5;
struct sa
{
    int id, sc;
    char name[105];
} arr[MAXN];
bool cmp(sa a, sa b)
{
    if(a.id == b.id)
        return a.sc > b.sc;
    return a.id < b.id;
}
int main()
{
    int n, m;
    while(cin>>n>>m)
    {
        for(int i=0; i<n; i++)
        {
            cin>>arr[i].name>>arr[i].id>>arr[i].sc;
        }
        sort(arr, arr+n, cmp);
        int d = 0;
        arr[n].id = -1;///小技巧
        for(int i=1; i<=n; i++)
        {
            if(arr[i].id != arr[i-1].id)
            {
                if(i-d < 2)
                {
                    puts("?");
                    d = i;
                    continue;
                }
                if(i-d == 2)///需要注意这里
                {
                    cout<<arr[d].name<<" "<<arr[d+1].name<<endl;
                    d = i;
                    continue;
                }
                if(arr[d+1].sc != arr[d+2].sc)
                {
                    cout<<arr[d].name<<" "<<arr[d+1].name<<endl;
                }
                else
                {
                    puts("?");
                }
                d = i;
            }
        }
    }
    return 0;
}

第二个是用vector数组写的:

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstdio>
#include <cstdlib>

using namespace std;
const int MAXN = 1e5+5;
struct sa
{
    int id, sc;
    char name[105];
} arr[MAXN];

bool cmp(sa a, sa b)
{
    if(a.id == b.id)
        return a.sc > b.sc;
    return a.id < b.id;
}

vector <sa> vec[MAXN];
int main()
{
    int n, m;
    while(cin>>n>>m)
    {
        for(int i=0; i<n; i++)
        {
            cin>>arr[i].name>>arr[i].id>>arr[i].sc;
            vec[arr[i].id].push_back(arr[i]);
        }
        for(int i=1; i<=m; i++)
        {
            sort(vec[i].begin(), vec[i].end(), cmp);
            if(vec[i].size() == 1)
            {
                puts("?");
            }
            else if(vec[i].size() == 2)
                cout<<vec[i][0].name<<" "<<vec[i][1].name<<endl;
            else
            {
                if(vec[i][1].sc == vec[i][2].sc)
                    puts("?");
                else
                    cout<<vec[i][0].name<<" "<<vec[i][1].name<<endl;
            }
        }
    }
    return 0;
}
时间: 2024-10-11 04:34:45

CodeForces 659 B. Qualifying Contest(结构体排序的问题)的相关文章

Codeforces Round #415 (Div. 2) B. Summer sell-off(贪心+结构体排序)

题目链接:http://codeforces.com/contest/810/problem/B 题意:给定天数和货物可以翻倍的天数,每天都有一定的货物量和顾客数,问怎么样货物才能卖得最多(前一天的货物不会留到下一天,每个顾客只能买一个货物). 简单的贪心问题,贪心策略是:如果两倍的货物量卖出去的更多,就选两倍的,否则就选一倍的. 那一天能卖出去的货物量:min(货物量,顾客数).然后根据结构体排序一下就ok了 1 #include <iostream> 2 #include <algo

CodeForces 151 B 结构体排序。

E - 结构体又来了呦 Time Limit:2000MS     Memory Limit:262144KB     64bit IO Format:%I64d & %I64u Submit Status Practice CodeForces 151B Description Winters are just damn freezing cold in Nvodsk! That's why a group of n friends prefers to take a taxi, order

hdu 1069 Monkey and Banana (结构体排序,也属于简单的dp)

Monkey and Banana Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7770    Accepted Submission(s): 4003 Problem Description A group of researchers are designing an experiment to test the IQ of a

【转】 从最简单的vector中sort用法到自定义比较函数comp后对结构体排序的sort算法

sort函数在使用中非常好用,也非常简单,而且效率与冒泡或者选择排序不是一个数量级.本文就sort函数在vector中的用法分为sort函数入门用法与自定义comp比较函数比较结构体这两个最基本的功能讲讲其用法: 1.sort入门: 使用sort需要包含algorithm头文件,完整代码如下 #include<iostream> #include<vector> #include<algorithm>//貌似可以不用,但最好加上. using namespace std

HDU 1084 [What Is Your Grade?] 结构体排序

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1084 题目大意:共5道题,N个学生.做出5道满分,0道50分.做出1-4道的同学,若在前50%(向下取整),则获得95.85.75.65,若在后50%则获得90.80.70.60. 关键思想:结构体排序 //结构体排序,考虑边界 #include <iostream> #include <algorithm> #include <cmath> #include <me

C++结构体排序

在C++中,对结构体的排序方式比C语言丰富的多.在C语言中,我们主要是通过qsort进行排序操作(抛开手写排序算法不说). 在C++<algorithm>中,有一个十分强大的排序函数sort,他的内部综合了许多种排序算法,因此非常高效.并且,用它来对结构体排序也十分方便. 先贴一段示例代码: 1 #include <cstdio> 2 #include <queue> 3 #include <vector> 4 #include <algorithm&

结构体排序

经常碰到结构体排序的问题,在此总结一下.以一个简单的例题开始: 例1.有三个人(Person结构体),每个人都有name(string型)和age(int型)两个属性,现在需要按照下面的规则排序:先以姓名按从小到大排序(如abc<abd),如果姓名相同,则按照年龄从大到小排序. #include<iostream> #include<string> using namespace std; struct Person{ string name; int age; }; voi

HDOJ 1009. Fat Mouse&#39; Trade 贪心 结构体排序

FatMouse' Trade Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 56784    Accepted Submission(s): 19009 Problem Description FatMouse prepared M pounds of cat food, ready to trade with the cats g

最小生成树模板+并查集(隐藏)+结构体排序模板

minn[101],g[101][101],u[101]; memset(u,1,sizeof(u)); memset(minn,0x7f,sizeof(minn)); minn[1]=0; u[1]=0; i,j,k,m; total=0; for(i=1;i<=n;i++) { k=0; for(j=1;j<=n;j++) if(u[j]&&(minn[k]>minn[j])) k=j; u[k]=0; for(j=1;j<=n;j++) if(u[j]&