排序
- 时间复杂度
-
- 时间复杂度在百万级以下
code2.1
#include <bits/stdc++.h>
#define FF(A,B) for(int A = 0;A<B;A++)
using namespace std;
int main(){
int n;
int buf[100];
bool firstCase = true;
while(scanf("%d",&n) != EOF){
FF(i,n)
scanf("%d",&buf[i]);
FF(i,n){
FF(j,n-1-i){
if(buf[j] > buf[j+1]){
int tmp = buf[j];
buf[j] = buf[j+1];
buf[j+1] = tmp;
}
}
}//Bubble Sort
FF(i,n)
printf("%d ",buf[i]);
printf("\n");
}
return 0;
}
scanf是有返回值的,返回值为被输入函数赋值的变量个数
在本题中:n为一个整数,若进行了赋值,则返回1,若输入已经到达结尾(输入文件到达末尾或在命令行输入中输入了ctrl+z,则返回EOF
若输入为字符串采用gets()方法:则相同功能的循环判断语句为while(gets(字符串变量))
code 2.4 成绩排序
利用sort(x,y,cmp)函数时,cmp的定义规则为只要cmp的返回值为true时,cmp函数的第一个参数将会排在第二个函数之前
#include <bits/stdc++.h>
using namespace std;
struct E{
char name[101];
int age;
int score;
}buf[100];
bool cmp(E a,E b){
if(a.score!=b.score)
return a.score < b.score;
int tmp = strcmp(a.name,b.name);
if(tmp!=0)
return tmp < 0;
else
return a.age < b.age;
}
int main()
{
int n;
while(scanf("%d",&n)!=EOF){
for(int i = 0;i < n;i++)
scanf("%s%d%d",buf[i].name,&buf[i].age,&buf[i].score);
sort(buf,buf+n,cmp);
for(int i = 0;i<n;i++){
printf("%s %d %d\n",buf[i].name,buf[i].age,buf[i].score);
}
}
return 0;
}
在定义了结构体的情况下有两种方法实现排序。
其一是利用cmp函数的定义来实现排序规则
其二是在未输入cmp参数,即默认情况下,在结构体中重载operator < 来实现默认排序的规则。
code2.6
#include <bits/stdc++.h>
#define ISYEAR(x) x % 100 != 0 && x % 4 == 0 || x % 400 == 0 ? 1 : 0
// 定义宏判断是否是闰年,方便计算每月天数
using namespace std;
int dayOfMonth[13][2]{
0,0,
31,31,
28,29,
31,31,
30,30,
31,31,
30,30,
31,31,
31,31,
30,30,
31,31,
30,30,
31,31,
};
struct Date{
int Day;
int Month;
int Year;
void nextDay(){
Day++;
if(Day > dayOfMonth[Month][ISYEAR(Year)]){
Day = 1;
Month++;
if(Month > 12){
Month = 1;
Year++;
}
}
}
};
int buf[5001][13][32];
int main()
{
Date tmp;
int cnt = 0;
tmp.Day = 1;
tmp.Month = 1;
tmp.Year = 0;
while(tmp.Year != 5001){
buf[tmp.Year][tmp.Month][tmp.Day] = cnt;
tmp.nextDay();
cnt++;
}
int d1,m1,y1;
int d2,m2,y2;
while(scanf("%4d%2d%2d",&y1,&m2,&d1)!=EOF){
scanf("%4d%2d%2d",&y2,&m2,&d2);
printf("%d\n",abs(buf[y2][m2][d2] - buf[y1][m1][d1]));
}
return 0;
}
本算法利用思想:
Hash思想
printf()技巧:%4d来读取该八位数字的前四位并赋值给代表年的变量,后面同理。
buf[5001][13][32]这种极大极耗内存的数组,若在main()中定义会出现栈溢出而终止。所以以后要在全局空间内申请该类变量
code2.7
#include <bits/stdc++.h>
#define ISYEAR(x) x % 100 != 0 && x % 4 == 0 || x % 400 == 0 ? 1 : 0
// 定义宏判断是否是闰年,方便计算每月天数
using namespace std;
int dayOfMonth[13][2]{
0,0,
31,31,
28,29,
31,31,
30,30,
31,31,
30,30,
31,31,
31,31,
30,30,
31,31,
30,30,
31,31,
};
struct Date{
int Day;
int Month;
int Year;
void nextDay(){
Day++;
if(Day > dayOfMonth[Month][ISYEAR(Year)]){
Day = 1;
Month++;
if(Month > 12){
Month = 1;
Year++;
}
}
}
};
int buf[3001][13][32];
char monthName[13][20]{
"",
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December"
};//月名 每个月名对应下标1到12
char weekName[7][20]{
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday"
};
int main(){
Date tmp;
int cnt = 0;
tmp.Day = 1;
tmp.Month = 1;
tmp.Year = 0;
while(tmp.Year!=3001){
buf[tmp.Year][tmp.Month][tmp.Day] = cnt;
tmp.nextDay();
cnt++;
}
int d,m,y;
char s[20];
while(scanf("%d %s %d",&d,s,&y) != EOF){
for(m = 1;m <= 12;m++){
if(strcmp(s,monthName[m]) == 0){
break;
}
}
int days = buf[y][m][d] - buf[2012][7][15];//计算给定日期与今日日期的天数间隔(注意可能为负)
puts(weekName[(days%7+7)%7]);
}
return 0;
}
Hash的应用
code 2.8
#include <bits/stdc++.h>
#define MAXSIZE 101
using namespace std;
int buf[MAXSIZE] = {0};
int main()
{
int n;
while(scanf("%d",&n) != EOF){
memset(buf,0,sizeof(int)*101);
for(int i = 1;i <= n;i++){
int x;
scanf("%d",&x);
buf[x]++;
}
int x;
scanf("%d",&x);
printf("%d\n",buf[x]);
}
return 0;
}
code2.9
#include <bits/stdc++.h>
#define OFFSET 500000
int Hash[1000001];//hash数组,记录每个数字是否出现,不出现为0,出现为1
int main(){
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
memset(Hash,0,1000001*sizeof(int));
for(int i = 1;i <= n;i++){
int x;
scanf("%d",&x);
Hash[x + OFFSET] = 1;
}
for(int i = 500000;i >= -500000;i--){
if(Hash[i+OFFSET] == 1){
printf("%d",i);
m--;
if(m != 0)
printf(" ");
else{
printf("\n");
break;
}
}
}
}
return 0;
}