第一模块:排序
A.51Nod-2138
题目描述:
给定n个字符串,按字典序从小到大输出,所有字符串都由小写字母组成,开头字母全都不同,字符串两两之间用一个空格分隔。
AC代码:
#include<iostream>
using namespace std;
string a[30],temp;
int main()
{
int n;
cin >> n;
for(int i = 0;i < n;i++){
cin >> a[i];
}
for(int i = 0;i < n - 1;i++){
for(int j = 0;j < n - i - 1;j++){
if(a[j] > a[j + 1]){
temp = a[j + 1];
a[j + 1] = a[j];
a[j] = temp;
}
}
}
for(int i = 0;i < n;i++){
cout << a[i] << ' ';
}
return 0;
}
本题需要注意的是,存放这N个字符串的时候,如果是用char类型存放不太好处理,因为对每一个字符串的处理都是对于整体,但是开string的话就可以解决这个问题,直接用string数组存放每一个字符串。其次由于N比较小所以直接冒泡排序就可。
B.OJ-3682
题目描述:
输入10个整数,彼此以空格分隔
重新排序以后输出,要求:先输出奇数,从大到小,再输出偶数,从小到大
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int a[15] = {},even[15] = {},uneven[15] = {};
int main()
{
std::ios::sync_with_stdio(false);
while(cin >> a[0] >> a[1] >> a[2] >> a[3] >> a[4] >> a[5] >> a[6] >> a[7] >> a[8] >> a[9]){
int k = 0,l = 0;
for(int i = 0;i < 10;i++){
if(a[i]%2 == 0||a[i] == 0){ //记录偶数
even[k] = a[i];
k++;
}
else if(a[i]%2 != 0&&a[i] != 0){ //记录奇数
uneven[l] = a[i];
l++;
}
}
sort(even,even + k);
sort(uneven,uneven + l);
for(int i = l - 1;i >= 0;i--){
cout << uneven[i] << ' ';
}
for(int i = 0;i < k - 1;i++){
cout << even[i] << ' ';
}
cout << even[k - 1] << endl;
}
return 0;
}
对这个题目的话,首先N的取值是0-100,所以直接sort就可以,剩下的就是把奇数偶数分别提出来,排序后输出即可。注意这里的输出格式需要控制一下不然可能给PE了。
C.51Nod-2058
题目描述:
输入一个整数n(n <= 10000)和n个整数。对这n个数从小到大进行排序,输出排序结果。
AC代码
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
#define LL long long
const int maxn = 1e5 + 10;
LL a[maxn] = {},b[maxn] = {};
void quick_sort(int l,int r)
{
if(r - l <= 0)return ;
int now = a[l];
int p = l,q = r;
for(int i = l + 1;i <= r;i++){
if(a[i] <= now) b[p++] = a[i];
else b[q--] = a[i];
}
b[p] = now;
for(int i = l;i <= r;i++){
a[i] = b[i];
}
quick_sort(l,p - 1);
quick_sort(p + 1,r);
}
int main()
{
std::ios::sync_with_stdio(false);
int n;
cin >> n;
for(int i = 0;i < n;i++){
cin >> a[i];
}
quick_sort(0,n - 1);
for(int i = 0;i < n;i++){
cout << a[i] << endl;
}
return 0;
}
首先数据到了10000,直接用sort,选择排序,冒泡排序基本就是找TEL…
所以这个直接就用快排了,这里感谢Dcm师哥的板子TAT。
D.HDU-2020
题目描述:
输入n(n<=100)个整数,按照绝对值从大到小排序后输出。题目保证对于每一个测试实例,所有的数的绝对值都不相等。
#include<bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn = 105;
LL a[maxn] = {};
bool cmd(int a,int b)
{
if(a != b) return abs(a) > abs(b);
}
int main()
{
int n;
while(cin >> n){
if(n == 0) return 0;
for(int i = 0;i < n;i++){
cin >> a[i];
}
sort(a,a + n,cmd);
for(int i = 0;i < n - 1;i++){
cout << a[i] << ' ';
}
cout << a[n - 1] << endl;
}
return 0;
}
首先这个可以直接用sort,QAQ
然后一开始比较困惑的地方在于怎样保证绝对值比较的前提下进行正常输出,后来也是突然想到了自定义cmd函数,这样的话问题就好解决多了。
E.Gym-247873C
题目描述:
n个数,排序
Input:
第一行一个整数n,(1 <= n <= 6000000)
接下来n行每行一个整数ai(1<=ai<=100000)
AC代码:
#include<algorithm>
using namespace std;
const int maxn = 6e6 + 5;
int a[maxn] = {};
int main()
{
int n;
scanf("%d",&n);
for(int i = 0;i < n;i++){
scanf("%d",&a[i]);
}
sort(a,a + n);
for(int i = 0;i < n - 1;i++){
printf("%d\n",a[i]);
}
printf("%d",a[n - 1]);
return 0;
}
我其实觉得这个题我没啥说的,一开始用cin/cout做然后T掉了,后来硬是改成了scanf/printf就骗过去了(3000ms的时间我跑了2292ms)
F.51Nod-2134
题目描述:
输入一个长度为n的数组,输出逆序对的个数,也就是说问有多少对(i, j)满足1 <= i < j <= n,且ai > aj。
1 <= n <= 1000
1 <= ai <= 1e9
AC代码:
#include<iostream>
#define LL long long
using namespace std;
const int MAXN = 50000+5;
const int MAXM = 1e5;
int a[MAXN],temp[MAXN];
LL ans=0;
int n;
void merge(int le,int mid,int ri)
{
int i,j,k;
i = le;j = mid + 1;k = le;
for(;i <= mid&&j <= ri;){
if(a[i] > a[j]){
temp[k++] = a[j++];
ans += mid - i + 1;
}
else temp[k++] = a[i++];
}
while(i <= mid) temp[k++] = a[i++];
while(j <= ri) temp[k++] = a[j++];
for(i = le;i <= ri;i++) a[i] = temp[i];
}
void merge_sort(int le,int ri){
if(le < ri){
int mid = (le + ri) >> 1;
merge_sort(le,mid);
merge_sort(mid + 1,ri);
merge(le,mid,ri);
}
}
int main(){
scanf("%d",&n);
for(int i = 0;i < n;i++) scanf("%d",&a[i]);
ans = 0;
merge_sort(0,n - 1);
printf("%lld\n",ans);
return 0;
}
这个题其实可以直接暴力二重循环,因为数比较小可以直接做。但是似乎更好的方法是归并排序,每次在并的时候进行判断,如果满足逆序条件就给他叠加一下。这个是最后看了题解+各路大神对归并排序的讲解后才明白了一点,积累方法吧TAT。