PTA排序练习

7-1 选择法排序

本题要求将给定的n个整数从大到小排序后输出。

输入格式:

输入第一行给出一个不超过10的正整数n。第二行给出n个整数,其间以空格分隔。

输出格式:

在一行中输出从大到小有序的数列,相邻数字间有一个空格,行末不得有多余空格。

输入样例:

4
5 1 7 6

输出样例:

7 6 5 1

代码如下:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int n;
    cin>>n;
    int a[n];
    for(int i=0;i<n;i++){
        cin>>a[i];
    }
    for(int i=0;i<n;i++){
        int min=i,temp;
        for(int j=i+1;j<n;j++){
            if(a[min]<a[j])
                min=j;
        }
        temp=a[i];
        a[i]=a[min];
        a[min]=temp;
    }
    cout<<a[0];
    for(int i=1;i<n;i++){
        cout<<" "<<a[i];
    }
    return 0;
}

7-2 冒泡法排序

将N个整数按从小到大排序的冒泡排序法是这样工作的:从头到尾比较相邻两个元素,如果前面的元素大于其紧随的后面元素,则交换它们。通过一遍扫描,则最后一个元素必定是最大的元素。然后用同样的方法对前N−1个元素进行第二遍扫描。依此类推,最后只需处理两个元素,就完成了对N个数的排序。

本题要求对任意给定的K(<N),输出扫描完第K遍后的中间结果数列。

输入格式:

输入在第1行中给出N和K(1≤K<N≤100),在第2行中给出N个待排序的整数,数字间以空格分隔。

输出格式:

在一行中输出冒泡排序法扫描完第K遍后的中间结果数列,数字间以空格分隔,但末尾不得有多余空格。

输入样例:

6 2
2 3 5 1 6 4

输出样例:

2 1 3 4 5 6

代码如下:

#include<bits/stdc++.h>
using namespace std;
int main(){
    int N,K;
    cin>>N>>K;
    int a[N];
    for(int i=0;i<N;i++){
        cin>>a[i];
    }
    for(int i=0;i<K;i++){
        for(int j=0;j<N-i-1;j++){
            if(a[j]>a[j+1]){
                int temp=a[j];
                a[j]=a[j+1];
                a[j+1]=temp;
            }
        }
    }
    cout<<a[0];
    for(int i=1;i<N;i++){
        cout<<" "<<a[i];
    }
    return 0;
}

7-3 两个有序链表序列的合并

已知两个非降序链表序列S1与S2,设计函数构造出S1与S2合并后的新的非降序链表S3。

输入格式:

输入分两行,分别在每行给出由若干个正整数构成的非降序序列,用−1表示序列的结尾(−1不属于这个序列)。数字用空格间隔。

输出格式:

在一行中输出合并后新的非降序链表,数字间用空格分开,结尾不能有多余空格;若新链表为空,输出NULL

输入样例:

1 3 5 -1
2 4 6 8 10 -1

输出样例:

1 2 3 4 5 6 8 10

代码如下:

#include <iostream>
#include <stdlib.h>
using namespace std;
typedef struct LNode 
{
	int data;
	struct LNode* next;
}LNode, * LinkList;
void List_creat(LinkList &L)
{
	int x;
	LinkList s, r;
	L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL;
	r = L;
	cin >> x;
	while (x != -1)
	{
		s = (LinkList)malloc(sizeof(LNode));
		s->data = x;
		r->next = s;
		r = r->next;
		cin >> x;
	}
	r->next = NULL;
}
void List_print(LinkList &L)
{
    if(L->next==NULL)
    {
        cout<<"NULL";
        return;
    }
	LinkList r;
	r = L->next;
    cout<<r->data;
    r=r->next;
	while (r)
	{
		cout << " "<< r->data;
		r = r->next;
	}
}
LinkList Merge(LinkList &L1, LinkList &L2)
{
	LinkList L, p, q, r;
	L = (LinkList)malloc(sizeof(LNode));
	L->next = NULL;
	r = L;
	p = L1->next;
	q = L2->next;
	while (p && q)
		if (p->data <= q->data)
		{
			r->next = p;
			r = r->next;
			p = p->next;
		}
		else 
        {
			r->next = q;
			r = r->next;
			q = q->next;
		}
	if (p) r->next = p;
	if (q) r->next = q;
	return L;
}
int main()
{
	LinkList L1 = NULL, L2 = NULL, L = NULL;
	List_creat(L1);
	List_creat(L2);
	L = Merge(L1, L2);
	List_print(L);
	return 0;
}

7-4 插入排序还是堆排序

根据维基百科的定义:

插入排序是迭代算法,逐一获得输入数据,逐步产生有序的输出序列。每步迭代中,算法从输入序列中取出一元素,将之插入有序序列中正确的位置。如此迭代直到全部元素有序。

堆排序也是将输入分为有序和无序两部分,迭代地从无序部分找出最大元素放入有序部分。它利用了大根堆的堆顶元素最大这一特征,使得在当前无序区中选取最大元素变得简单。

现给定原始序列和由某排序算法产生的中间序列,请你判断该算法究竟是哪种排序算法?

输入格式:

输入在第一行给出正整数 N (≤100);随后一行给出原始序列的 N 个整数;最后一行给出由某排序算法产生的中间序列。这里假设排序的目标序列是升序。数字间以空格分隔。

输出格式:

首先在第 1 行中输出Insertion Sort表示插入排序、或Heap Sort表示堆排序;然后在第 2 行中输出用该排序算法再迭代一轮的结果序列。题目保证每组测试的结果是唯一的。数字间以空格分隔,且行首尾不得有多余空格。

输入样例 1:

10
3 1 2 8 7 5 9 4 6 0
1 2 3 7 8 5 9 4 6 0

输出样例 1:

Insertion Sort
1 2 3 5 7 8 9 4 6 0

输入样例 2:

10
3 1 2 8 7 5 9 4 6 0
6 4 5 1 0 3 2 7 8 9

输出样例 2:

Heap Sort
5 4 3 1 0 2 6 7 8 9

代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N = 110;
int a[N], b[N], tmp[N];
int main() {
    int n;
    cin >> n;
    for (int i = 0; i < n; i++) cin >> a[i];
    for (int i = 0; i < n; i++) cin >> b[i];
    memcpy(tmp, a, sizeof (tmp));
    bool flag = 0;
    for (int i = 2; i <= n; i++) {
        sort(a, a + i);
        if (flag) {
            cout << "Insertion Sort" << endl;
            for (int j = 0; j < n; j++) {
                if (j) cout << " " << a[j];
                else cout << a[j];
            }
            break;
        }
        if (equal(a, a + n, b)) flag = 1;
    }
    if (!flag) {
        memcpy(a, tmp, sizeof (a));
        for (int i = n; i >= 1; i--) {
            make_heap(a, a + i);
            if (flag) {
                cout << "Heap Sort" << endl;
                for (int j = 0; j < n; j++) {
                    if (j) cout << " " << a[j];
                    else cout << a[j];
                }
                break;
            }
            if (equal(a, a + n, b)) flag = 1;
            swap(a[0], a[i - 1]);
        }
    }
    return 0;
}

7-5 PAT排名汇总

计算机程序设计能力考试(Programming Ability Test,简称PAT)旨在通过统一组织的在线考试及自动评测方法客观地评判考生的算法设计与程序设计实现能力,科学的评价计算机程序设计人才,为企业选拔人才提供参考标准(网址http://www.patest.cn)。

每次考试会在若干个不同的考点同时举行,每个考点用局域网,产生本考点的成绩。考试结束后,各个考点的成绩将即刻汇总成一张总的排名表。

现在就请你写一个程序自动归并各个考点的成绩并生成总排名表。

输入格式:

输入的第一行给出一个正整数N(≤100),代表考点总数。随后给出N个考点的成绩,格式为:首先一行给出正整数K(≤300),代表该考点的考生总数;随后K行,每行给出1个考生的信息,包括考号(由13位整数字组成)和得分(为[0,100]区间内的整数),中间用空格分隔。

输出格式:

首先在第一行里输出考生总数。随后输出汇总的排名表,每个考生的信息占一行,顺序为:考号、最终排名、考点编号、在该考点的排名。其中考点按输入给出的顺序从1到N编号。考生的输出须按最终排名的非递减顺序输出,获得相同分数的考生应有相同名次,并按考号的递增顺序输出。

输入样例:

2
5
1234567890001 95
1234567890005 100
1234567890003 95
1234567890002 77
1234567890004 85
4
1234567890013 65
1234567890011 25
1234567890014 100
1234567890012 85

输出样例:

9
1234567890005 1 1 1
1234567890014 1 2 1
1234567890001 3 1 2
1234567890003 3 1 2
1234567890004 5 1 4
1234567890012 5 2 2
1234567890002 7 1 5
1234567890013 8 2 3
1234567890011 9 2 4

代码如下:

#include<bits/stdc++.h>
using namespace std;
struct node
{
    string num;
    int score,rank[2],place;
};
bool cmp(node a, node b)
{
    if (a.score == b.score)
        return a.num < b.num;
    else
        return a.score > b.score;
}
struct node* a = new struct node[30010];
int* front = new int[30010];
int main()
{
    int N,k = 0,sum = 0;
    cin >> N;
    for (int c = 1; c <= N; c++)
    {
        int M = 0,value = k - 1;
        cin >> M;
        sum += M;
        for (int i = k; i < k + M; i++){
            a[i].place = c;
            cin>>a[i].num>>a[i].score;
            front[i] = i;
        }
        sort(a + k, a + k + M, cmp);
        for (int i = k; i < k + M; i++){
            if (i == 0 || a[i].score != a[i - 1].score)
                a[i].rank[0] = i - value;
            else{
                front[i] = front[i - 1];
                int temp = i;
                while (front[temp] != temp)
                    temp = temp - 1;
                a[i].rank[0] = temp - value;
            }
        }
        k+=M;
    }
    sort(a, a + sum, cmp);
    for (int i = 0; i < sum; i++)
        front[i] = i;
    for (int i = 0; i < sum; i++){
        if (i == 0 || a[i].score != a[i - 1].score)
            a[i].rank[1] = i + 1;
        else{
            front[i] = front[i - 1];
            int temp = i;
            while (front[temp] != temp)
                temp = temp - 1;
            a[i].rank[1] = temp + 1;
        }
    }
    cout << sum << endl;
    for (int i = 0; i < sum; i++){
        printf("%s %d %d %d",a[i].num.c_str(),a[i].rank[1], a[i].place, a[i].rank[0]);
        if (i != sum - 1)printf("\n");
    }
    delete[]a;
    delete[]front;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值