CSP初赛复习-16排序-真题分析
1 NOIP2010 阅读程序
#include <iostream>
using namespace std;
void swap(int & a, int & b)//函数引用传值 引用是别名,函数内修改对应调用函数也会改变
{
int t;
t = a;
a = b;
b = t;
}
int main()
{
int a1, a2, a3, x;
cin>>a1>>a2>>a3;
// 示例 5 4 3
if (a1 > a2)
swap(a1, a2);//a1>a2 交换 执行后 a1 < a2 变成4 5 3
if (a2 > a3)
swap(a2, a3);//a2>a3 交换 执行后a2<a3 变成4 3 5
if (a1 > a2)
swap(a1, a2);//a1>a2 交换 执行后 a1 < a2 变成3 4 5
//此时 a1 a2 a3 从小到大排好序
cin>>x;//输入x
if (x < a2)//x<a2
if (x < a1) //x<a2 && x<a1 最小 插入最前面
cout<<x<<' '<<a1<<' '<<a2<<' '<<a3<<endl;
else//x<a2 && x>=a1 插入a1和a2之间
cout<<a1<<' '<<x<<' '<<a2<<' '<<a3<<endl;
else//x>=a2
if (x < a3) //x>=a2 && x<a3 插入a2和a3直接
cout<<a1<<' '<<a2<<' '<<x<<' '<<a3<<endl;
else//x>=a3 插入a3后面
cout<<a1<<' '<<a2<<' '<<a3<<' '<<x<<endl;
return 0;
}
/*
输入
91 2 20
77
*/
分析
此程序分两部分
1 对a1 a2 a3从小到大排序
2 把x插入到a1 a2 a3 合适位置,使得a1 a2 a3 x四个数从小到大排序
根据上面输入
91 2 20
77
因此对上面输入a1 a2 a3 x从小到大排序
输出
2 20 77 90
2 NOIP2010 阅读程序
#include<iostream>
using namespace std;
int main()
{
const int SIZE=100;
int na,nb,a[SIZE],b[SIZE],i,j,k;
cin>>na;//输入一个数na
for(i=1;i<=na;i++)//输入na个对应数字对a数组 -数组中从小到大有序
cin>>a[i];
cin>>nb;//输入一个数nb
for(i=1;i<=nb;i++)//输入nb个对应数字到b数组 -数组中从小到大有序
cin>>b[i];
i=1;
j=1;
while( (i<=na)&&(j<=nb) )//i 1~na j 1~nb
{ //如下判断每次在a,b两个数组中取最小的一个数输出
if(a[i]<=b[j])//如果a[i]<=b[j] 输出a[i]
{
cout<<a[i]<<' ';
i++;
}
else//输入b[j]<a[i] 输出b[j]
{
cout<<b[j]<<' ';
j++;
}
}
if(i<=na)//如果a数组没有输出完 把a数组未输出的数字输出
for(k=i;k<=na;k++)
cout<<a[k]<<' ';
if(j<=nb)//如果b数组没有输出完 把b数组未输出的数字输出
for(k=j;k<=nb;k++)
cout<<b[k]<<' ';
return 0;
}
/*
输入:
5
1 3 5 7 9
4
2 6 10 14
*/
分析
此程序类似归并排序的合并过程
while 循环输出a,b数组中较小的数

while循环结束,a数组还有数字未输出,输出5和7

3 NOIP2011 阅读程序
#include<iostream>
#include<cstring>
using namespace std;
const int SIZE = 100;
int main()
{
int n,i,sum,x,a[SIZE];
cin>>n;
//sizeof(a)是数组大小*4(int 占4个字节) 由于前面定义数组元素为100,所以sizeof(a)=400
memset(a,0,sizeof(a));//对数组进行初始0 按位初始二进制
for(i=1;i<=n;i++){
cin>>x;
a[x]++;//计数排序
}
i=0;
sum=0;
while(sum<(n/2+1)){
i++;
sum+=a[i];
}
cout<<i<<endl;
return 0;
}
/*
输入:
11
4 5 6 6 4 3 3 2 3 2 1
*/
分析
通过计数排序对下列数放到对应数组中
11
4 5 6 6 4 3 3 2 3 2 1
根据计算排序对a数组初始数据结果如下

对代码进行分析
i=0;
sum=0;
while(sum<(n/2+1)){//n/2+1=6
i++;
sum+=a[i];
}
cout<<i<<endl;
所以
i=0 sum=0 0<6 执行后 i=1 sum=1
i=1 sum=1 1<6 执行后 i=2 sum=1+2=3
i=2 sum=3 3<6 执行后 i=3 sum=3+3=6
i=3 sum=6 6<6不满足条件退出
所以i=3
4 NOIP2014 阅读程序
#include <stdio.h>
#include <string.h>
const int SIZE = 100;
const int LENGTH = 25;
/*
* strcmp(a,b) <0:a的字典序小于b
* strcmp(a,b) =0:a和b一样
* strcmp(a,b) >0:a的字典序大于b
*/
int main()
{
char dict[SIZE][LENGTH + 1];
int rank[SIZE];
int ind[SIZE];
int i, j, n, tmp;
scanf( "%d", &n );
for ( i = 1; i <= n; i++ )
{
rank [i] = i;//此行在后续排序没有使用 可以去除
ind[i] = i;//字符串的位置
scanf( "%s", dict[i] );
}
for ( i = 1; i < n; i++ )//毛坯排序
for ( j = 1; j <= n - i; j++ )
if ( strcmp( dict[ind[j]], dict[ind[j + 1]] ) > 0 )
{//交换位置
tmp = ind[j];
ind[j] = ind[j + 1];
ind[j + 1] = tmp;
}
for ( i = 1; i <= n; i++ )//使用类似计数排序安排对应位置
rank[ind[i]] = i;
for ( i = 1; i <= n; i++ )
printf( "%d ", rank[i] );
printf( "\n" );
return(0);
}
/*
输入:
7
aaa
aba
bbb
aaa
aaa
ccc
aa
*/
模拟简单数据
3
aba
bbb
aaa
3个数冒泡排序,需要进行3-1=2趟
第1趟比较2次
第2趟比较1次
比较后顺序如下

把此顺序按数字下标放入rank排序数组,此思想类似计数排序

输出rank数组对应值,即
第1个aba排第2,第2个bbb排第3,第3个aaa排第1
CSP初赛复习-16-数据结构-排序-练习题
https://www.cnblogs.com/myeln/articles/17574468.html
作者:newcode 更多资源请关注纽扣编程微信公众号

从事机器人比赛、机器人等级考试、少儿scratch编程、信息学奥赛等研究学习

浙公网安备 33010602011771号