您的位置:首页 > 其它

排序、检索2016.2.5

2016-03-01 10:58 113 查看
1、HDU 1862 EXCEL排序(结构体排序练习)

题意:

对一个结构体以不同的标准进行排序。

解题思路:

看到题目中对结构体数组元素数目限制为小于1000000,我果断使用了系统排序函数qsort(),应为不论是冒泡排序还是选择排序,运算量过于庞大,必将会超时。题目中在以姓名和成绩排序时使用到了结构体二级排序,即如果首先排序对象相同时,以二级排序对象来确定数组元素的顺序。所以本题只需要确定三个不同的cmp()函数,以实现用不同的标准进行排序。另外看示范输出可知学号得以字符串形式存储。

Description

Excel可以对一组纪录按任意指定列排序。现请你编写程序实现类似功能。

Input

测试输入包含若干测试用例。每个测试用例的第1行包含两个整数 N (<=100000) 和 C,其中 N 是纪录的条数,C 是指定排序的列号。以下有 N

行,每行包含一条学生纪录。每条学生纪录由学号(6位数字,同组测试中没有重复的学号)、姓名(不超过8位且不包含空格的字符串)、成绩(闭区间[0, 100]内的整数)组成,每个项目间用1个空格隔开。当读到 N=0 时,全部输入结束,相应的结果不要输出。

Output

对每个测试用例,首先输出1行“Case i:”,其中 i 是测试用例的编号(从1开始)。随后在 N 行中输出按要求排序后的结果,即:当 C=1 时,按学号递增排序;当 C=2时,按姓名的非递减字典序排序;当 C=3

时,按成绩的非递减排序。当若干学生具有相同姓名或者相同成绩时,则按他们的学号递增排序。

Sample Input

3 1

000007 James 85

000010 Amy 90

000001 Zoe 60

4 2

000007 James 85

000010 Amy 90

000001 Zoe 60

000002 James 98

4 3

000007 James 85

000010 Amy 90

000001 Zoe 60

000002 James 90

0 0

Sample Output

Case 1:

000001 Zoe 60

000007 James 85

000010 Amy 90

Case 2:

000010 Amy 90

000002 James 98

000007 James 85

000001 Zoe 60

Case 3:

000001 Zoe 60

000007 James 85

000002 James 90

000010 Amy 90

Source

浙大计算机研究生复试上机考试-2007年

Recommend

lcy

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>

using namespace std;

typedef struct _student {
char num[7];
char name[9];
int score;
}_Student;

_Student student[100001];

int cmpnum(const void *a, const void *b)
{
_Student *x = (_Student*)a;
_Student *y = (_Student*)b;
return strcmp(x->num, y->num) > 0 ? 1 : -1;
}

int cmpname(const void *a, const void *b)
{
_Student *x = (_Student *)a;
_Student *y = (_Student *)b;
if(strcmp(x->name, y->name) != 0) {
return strcmp(x->name, y->name) > 0 ? 1 : -1;
}
return strcmp(x->num, y->num) > 0 ? 1 : -1;
}

int cmpscore(const void *a, const void *b)
{
_Student *x = (_Student *)a;
_Student *y = (_Student *)b;
if(x->score != y->score) {
return x->score - y->score > 0 ? 1 : -1;
}
return strcmp(x->num, y->num) > 0 ? 1 : -1;
}

int main()
{
int N, C;
int i, j = 1;
while(scanf("%d%d", &N, &C) && N){
for(i=0; i<N; ++i){
scanf("%s%s%d", student[i].num, student[i].name, &student[i].score);
}
if(C == 1){
qsort(student, N, sizeof(student[0]), cmpnum);
}
else if(C == 2){
qsort(student, N, sizeof(student[0]), cmpname);
}
else if(C== 3){
qsort(student, N, sizeof(student[0]), cmpscore);
}
printf("Case %d:\n", j++);
for(i=0; i<N; ++i){
printf("%s %s %d\n", student[i].num, student[i].name, student[i].score);
}
}
return 0;
}


2、UVa 10474 Where is the Marble?(大理石在哪?)

#include <iostream>
#include <cstdlib>

using namespace std;

int cmp_num(const void *a, const void *b)
{
return (*(int *)a - *(int *)b);
}

int main()
{
int N, Q;
int x[10010];
int y[10010];
int i, j;
int Case = 0;

while (cin>>N>>Q && (!(N==0&&Q==0))) {
++Case;
cout<<"CASE# "<<Case<<":"<<endl;
for (i=0; i<N; ++i) {
cin>>x[i];
}
qsort(x, N, sizeof(int), cmp_num);
for (i=0; i<Q; ++i) {
cin>>y[i];
int flag = 0;
for (j=0; j<N; ++j) {
if (y[i] == x[j]) {
flag = 1;
cout<<y[i]<<" found at "<<j+1<<endl;
break;
}
}
if (0 == flag) {
cout<<y[i]<<" not found"<<endl;
}
}
}
return 0;
}


3、UVa 299 Train Swapping(列车交换)

题意:

先输入一个数L为需要排列的数的个数,接下来是L个无序的数字,任务是把其升序排列,计算需要交换几次。

解题思路:

这道题 实际就是冒泡 交换的模型是火车厢,只能相邻元素交换,也就是冒泡排序

只是在第二层循环内加一个计数的,就可以知道交换了几次。

#include <iostream>

using namespace std;

int main()
{
int N;
int num[60];
int i, j;

while (cin>>N) {
while (N--) {
int count = 0;
int L;
cin>>L;
for (i=0; i<L; ++i) {
cin>>num[i];
}
int t;
for (i=0; i<L-1; ++i) {
for (j=i+1; j<L; ++j) {
if (num[i] > num[j]) {
t = num[i]; num[i] = num[j]; num[j] = t;
++count;
}
}
}
cout<<"Optimal train swapping takes "<<count<<" swaps."<<endl;
}
}
return 0;
}


4、UVa 755 487–3279

题意:

将每次所有输入的字符串转化为电话号码的标准形式,并输出出现次数大于1的电话号码和出现次数,注意在连续的输出之间输出一个空行

解题思路:

(1)、将每次所有输入字符串转化为整数,统计整数的出现次数,将出现次数大于1 的整数存进数组

(2)、对数组进行排序

(3)、根据电话号码的标准形式输出整数,然后输出此整数出现的次数

#include <iostream>
#include <cstring>
#include <map>
#include <iomanip>
#include <cstdio>

using namespace std;

int main()
{
int n;
int num;
char directory[20];
int digital[25] = {2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 0, 7, 7, 8, 8, 8, 9, 9, 9};
int len;
int i;
//    while (cin>>n) {
while (scanf("%d", &n) != EOF) {
while (n--) {
scanf("%d", &num);
//            cin>>num;
map<int, int>Map;
while (num--) {
scanf("%s", directory);
//                cin>>directory;
len = strlen(directory);
int c = 0;
for (i=0; i<len; ++i) {
if (directory[i]=='-') {
continue;
} else if (directory[i] <= '9') {
c = c * 10 + directory[i] - '0';
} else if (directory[i] <= 'Y') {
c = c * 10 + digital[directory[i]-'A'];
}
}
Map[c] += 1;
}
int flag = 0;
for (map<int, int>::iterator j=Map.begin(); j!=Map.end(); ++j) {
if (j->second > 1) {
flag = 1;
printf("%03d-%04d %d\n", (j->first)/10000, (j->first)%10000, j->second);
//                    cout<<setfill('0')<<setw(3)<<(j->first)/10000;
//                    cout<<"-";
//                    cout<<setfill('0')<<setw(4)<<(j->first)%10000;
//                    cout<<" ";
//                    cout<<j->second<<endl;
}
}
if (0 == flag) {
printf("No duplicates.\n");
//                cout<<"No duplicates."<<endl;
}
if (n > 0) {
cout<<endl;
}
}
}
return 0;
}


5、UVa 400 Unix ls(Unix 的 ls 命令)

题意:

将输入的名字按照ASCII 值进行升序排序,然后以表格形式输出,要求是每行有60列,每个名字占的列数为最长名字长度加二,并且让列数达到最大。

解题思路:

1. 先用qsort()函数进行排序。

2. 求最大的列数,在求出对应的行数。

3. 用循环嵌套将结果输出。

#include <iostream>
#include <cstdlib>
#include <cstring>

using namespace std;

char filename[110][70];

int cmp_string(const void *a, const void *b)
{
return strcmp((char *)a, (char *)b);
}

int main()
{
int N;
int i, j, k, l;
int lie, hang;

char dashes[65] = "------------------------------------------------------------";

while (cin>>N) {
int len_max = 0;
for (i=0; i<N; ++i) {
cin>>filename[i];
if ((int)strlen(filename[i]) > len_max) {
len_max = strlen(filename[i]);
}
}
qsort(filename, N, sizeof(filename[0]), cmp_string);
lie = 60 / (len_max + 2);
if (lie == 0) {
lie = 1;
}
if (N%lie == 0) {
hang = N / lie;
} else {
hang = N / lie + 1;
}
cout<<dashes<<endl;
for (i=0; i<hang; ++i) {
for (j=i,k=0; (k<lie)&&(j<N); j+=hang,++k) {
cout<<filename[j];
for (l=0; l<(len_max + 2 - (int)strlen(filename[j])); ++l) {
cout<<" ";
}
}
cout<<endl;
}
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: