NYACM_008

来源:互联网 发布:乌鲁木齐乐知少儿英语 编辑:程序博客网 时间:2024/06/05 05:10

NYACM_008

题目:一种排序

链接:http://acm.nyist.net/JudgeOnline/problem.php?pid=8

描述:

描述
现在有很多长方形,每一个长方形都有一个编号,这个编号可以重复;还知道这个长方形的宽和长,编号、长、宽都是整数;现在要求按照一下方式排序(默认排序规则都是从小到大);

1.按照编号从小到大排序

2.对于编号相等的长方形,按照长方形的长排序;

3.如果编号和长都相同,按照长方形的宽排序;

4.如果编号、长、宽都相同,就只保留一个长方形用于排序,删除多余的长方形;最后排好序按照指定格式显示所有的长方形;
输入
第一行有一个整数 0< n<10000,表示接下来有n组测试数据;
每一组第一行有一个整数 0< m<1000,表示有m个长方形;
接下来的m行,每一行有三个数 ,第一个数表示长方形的编号,

第二个和第三个数值大的表示长,数值小的表示宽,相等
说明这是一个正方形(数据约定长宽与编号都小于10000);
输出
顺序输出每组数据的所有符合条件的长方形的 编号 长 宽
样例输入
1
8
1 1 1
1 1 1
1 1 2
1 2 1
1 2 2
2 1 1
2 1 2
2 2 1
样例输出
1 1 1
1 2 1
1 2 2
2 1 1
2 2 1

分析:

可以考虑使用多重map进行存储,首先以map< num, map< length,width> >存储数据,map自动对key排序,相同num的在一起,将相同num的数据再次放到一个multimap里面,存储的是相同编号的长宽multimap< length,width>,会自动对长进行排序,相同的处理逻辑,得到相同长度的宽值,输出即可。有点晚了,为了AC可能没考虑太多,感觉如果用链表或者树可能更快一点,首先有一个虚拟根节点,将第一个数据放进去,下一个数据如果编号相同,在相同编号的节点下比较长度,长度相同在相同的长度节点里面将宽度放在合适的地方,不过不同生存新的节点,然后输出。
=============================================
比如输入值为 (1 5 3,1 5 2, 1 3 2, 2 4 6)
则构造出如下图形
1.1 5 3
2.1 5 (2 3)
3.1 (3 2)(5 (2 3))
4.(1 (3 2)(5 (2 3)))(2 4 6)

=============================================

AC code:

#include <vector>#include <map>#include <algorithm>#include <iostream>#include <cmath>using namespace std;void CoutSameNumAndSameLength(int num, int length, map<int, int> data){    for (map<int, int>::iterator it = data.begin(); it != data.end(); it++)    {        cout << num << " " << length << " " << (*it).first << endl;;    }   }void CoutSameNum(int num,multimap<int,int> SameNumData){    map<int, int> SameLengthData;    int oldLength;    for (multimap<int, int>::iterator it = SameNumData.begin(); it != SameNumData.end(); it++)    {        if (it == SameNumData.begin())        {            //第一个            SameLengthData.clear();            oldLength = (*it).first;            SameLengthData.insert(pair<int, int>((*it).second, (*it).first));            continue;        }        if ((*it).first != oldLength)        {            //输出当前编号、长度数据            CoutSameNumAndSameLength(num, oldLength, SameLengthData);            SameLengthData.clear();            oldLength = (*it).first;            SameLengthData.insert(pair<int, int>((*it).second, (*it).first));        }        else        {            SameLengthData.insert(pair<int, int>((*it).second, (*it).first));        }    }    CoutSameNumAndSameLength(num, oldLength, SameLengthData);}//输出有序且不重复值,要么在存储时候进行过滤,要么在输出时候进行过滤int main(){    int n;    cin >> n;    while (n--)    {        int m;        cin >> m;        multimap<int, map<int, int> > data;        int tmp_num, tmp_length, tmp_width;        for (int i = 0; i < m; i++)        {            cin >> tmp_num >> tmp_length >> tmp_width;            if (tmp_length < tmp_width)            {                int tmpdata;                tmpdata = tmp_length;                tmp_length = tmp_width;                tmp_width = tmpdata;            }            map<int, int> tmp_data;            tmp_data[tmp_length] = tmp_width;                       data.insert(pair<int,map<int,int> >(tmp_num, tmp_data));        }        int oldnum = 20000, oldlength = 20000, oldwidth = 20000;        multimap<int, int> SameNumData;        //map只对key排序,相同编号的再次放到同一个multimap里面进行一次排序        for (multimap<int, map<int, int> >::iterator it = data.begin(); it != data.end(); it++)        {            if (it == data.begin())            {                //第一个数据                oldnum = (*it).first;                SameNumData.clear();                map<int, int> tmp_data;                tmp_data = (*it).second;                SameNumData.insert(pair<int, int>((*tmp_data.begin()).first, (*tmp_data.begin()).second));                continue;            }            if ((*it).first == oldnum)            {                //编号相同                map<int, int> tmp_data;                tmp_data = (*it).second;                SameNumData.insert(pair<int, int>((*tmp_data.begin()).first, (*tmp_data.begin()).second));            }            else            {                //下一个新的编号,输出当前编号数据,更新编号数据                CoutSameNum(oldnum, SameNumData);                oldnum = (*it).first;                SameNumData.clear();                map<int, int> tmp_data;                tmp_data = (*it).second;                SameNumData.insert(pair<int, int>((*tmp_data.begin()).first, (*tmp_data.begin()).second));            }        }        //输出最后一个相同编号的数据        CoutSameNum(oldnum, SameNumData);    }    return 0;}

其他:

有点困,脑子不够用了,勉强AC,16/312,下面几个比较快的有8/244,multimap肯定不是最佳的选择,哪怕数组感觉都可以更快,以后有机会用其他的结构实现下。
之前用codeblocks 多重map两个>>有提示要分开,
map< int, map< int,int>> ——> map< int, map< int,int> >
VS2015能够直接通过,提交错误,感觉VS2015检查不够严密,或者说太智能了,有时候少了头文件都能正确编译,对于做出产品自然更友好,不过不利于养成严谨的习惯,毕竟不是每一个编译器都这么给力,而又不可能非VS不用。

原创粉丝点击