生疏!生疏!生疏!生疏!生疏!生疏!
九度题目!
题目1061:成绩排序
http://ac.jobdu.com/problem.php?pid=1061
方案一:
Keyword:快速排序,sort,自定义规则
// 快速排序
#include <stdio.h>
#include <algorithm> // sort需要的头文件
#include <string.h>
using namespace std;// sort 定义在此命名空间中
struct S{
char name[100];
int age;
int score;
} buf[1000];
bool cmp(S x, S y){ //自定义排序规则
if (x.score != y.score) return x.score < y.score; // 分数不同,按成绩由低到高:排序后的要求是: x.score < y.score
int tmp = strcmp(x.name, y.name);
if (tmp != 0) return tmp<0; // 分数相同,姓名不同,字典顺序:不可用:x.name < y.name
else return x.age < y.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);// qsort
for (int i = 0; i < N; i++){
printf("%s %d %d\n", buf[i].name, buf[i].age, buf[i].score);
}// 输出
}
return 0;
}
方案二:
Keyword:快速排序,sort,重载运算符
// 快速排序
#include <stdio.h>
#include <algorithm> // sort需要的头文件
#include <string.h>
using namespace std;// sort 定义在此命名空间中
struct S{
char name[100];
int age;
int score;
bool operator < (const S &y) const{ // 利用C++定义重载小于运算符
if (score != y.score) return score < y.score; // 分数不同,按成绩由低到高
int tmp = strcmp(name, y.name);
if (tmp != 0) return tmp<0; // 分数相同,姓名不同,字典顺序:不可用:name < y.name
else return age < y.age; // 分数,姓名相同,按年龄
}
} buf[1000];
bool cmp(S x, S y){
if (x.score != y.score) return x.score < y.score; // 分数不同,按成绩由低到高
int tmp = strcmp(x.name, y.name);
if (tmp != 0) return tmp<0; // 分数相同,姓名不同,字典顺序:不可用:x.name < y.name
else return x.age < y.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);// qsort
sort(buf, buf+N);
for (int i = 0; i < N; i++){
printf("%s %d %d\n", buf[i].name, buf[i].age, buf[i].score);
}// 输出
}
return 0;
}
题目1023:EXCEL排序
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
struct S{
char id[10];
char name[10];
int score;
} buf[100010];//存放学生信息
bool cmp1(S x, S y){
int temp = strcmp(x.id, y.id);
return temp < 0;
}// 按学号排序
bool cmp2(S x, S y){
int temp = strcmp(x.name, y.name);
if (temp == 0)
return cmp1(x,y);
else
return temp < 0;
}// 按姓名排序,姓名相同时,按学号
bool cmp3(S x, S y){
if (x.score == y.score)
return cmp1(x,y);
else
return x.score < y.score;
}// 按成绩排序,成绩相同,按学号
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("E:\\in.txt","r",stdin);
#endif
int n, c;
int cn = 0; // 记录case id
while (scanf ("%d%d", &n, &c) && n != 0){
for (int i = 0; i < n; i++){
scanf ("%s %s %d", &buf[i].id, &buf[i].name, &buf[i].score);
}// 输入
if (c == 1) sort(buf,buf+n,cmp1);
else if (c == 2) sort(buf,buf+n,cmp2);
else if (c == 3) sort(buf,buf+n,cmp3);
else printf("C error!\n"); // 排序
cn++;
printf("Case %d:\n", cn);
for (int i = 0; i<n; i++){
printf("%s %s %d\n", buf[i].id, buf[i].name, buf[i].score);
/*------------------------------------------------
1、("%d %s %d", buf[i].id, buf[i].name, buf[i].score);
这条语句没有printf完全没有任何错误,输出的时候下我一跳
2、另外输出一行,要换行!!!
3、学号是6位,必须注意。用int时,前面的0会省略掉,需使用字符串
------------------------------------------------*/
}// 输出
}// while
return 0;
}
高亮:
采用这种结构体的定义时,
struct S{
int id;
char name[10];
int score;
}
同样可以正常输出id,并且前面的0不会省略。
printf(),%06d,这样就可以达到目的:0代表了用0填充,6代表宽度。
printf("%06d %s %d\n", buf[i].id, buf[i].name, buf[i].score);
题目1096:日期差值
-
有两个日期,求两个日期之间的天数,如果两个日期是连续的我们规定他们之间的天数为两天
题目描述:
-
输入:
-
有多组数据,每组数据有两行,分别表示两个日期,形式为YYYYMMDD
-
输出:
-
每组数据输出一行,即日期差值
-
样例输入:
-
20110412 20110422
-
样例输出:
-
11
-
方案
/**
* 这种算法是错误的,因为题目没有说第一个日期比第二个小
**/
/*
#include <stdio.h>
#define ISYEAP(x) x%100 != 0 && x%4 == 0 || x %400 == 0 ? 1:0
// 定义宏判断是否为瑞年
int dayOfMonth[13][2]={ //CE*1:少一个=还能是数组定义吗
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][ISYEAP(Year)]){
Day = 1;
Month++; // 进入下一月
if (Month > 12){
Month = 1;
Year++; // 进入下一年
}
}
}
};
int buf[5001][13][32]; // 存放预处理的天数
int Abs(int x){
return x>0 ? x:-x;
}
int main(){
Date date;
int cnd = 0; // count number of date:缩写,天数计数
int year1,month1,day1;
int year2,month2,day2;
while (scanf("%4d%2d%2d", &year1, &month1, &day1) != EOF){
scanf("%4d%2d%2d", &year2, &month2, &day2);
date.Day = day1;
date.Month = month1;
date.Year = year1; // 初始化日期对象为0年1月1日
while (date.Year != year2 || date.Month != month2 || date.Day != day2){
buf[date.Year][date.Month][date.Day] = cnd; // 将该日与0年1月1日的差保存
date.nextDay();// 计算下一天
cnd++; //计数器累加
} // while
printf("%d\n", cnd + 1);
}
return 0;
}
*/
#include <stdio.h>
#define ISYEAP(x) x%100 != 0 && x%4 == 0 || x %400 == 0 ? 1:0
// 定义宏判断是否为瑞年
int dayOfMonth[13][2]={ //CE*1:少一个=还能是数组定义吗
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][ISYEAP(Year)]){
Day = 1;
Month++; // 进入下一月
if (Month > 12){
Month = 1;
Year++; // 进入下一年
}
}
}
};
int buf[5001][13][32]; // 存放预处理的天数
int Abs(int x){
return x>0 ? x:-x;
}
int main(){
Date date;
int cnd = 0; // count number of date:缩写,天数计数
date.Day = 1;
date.Month = 1;
date.Year = 0; // 初始化日期对象为0年1月1日
while (date.Year != 5001){
buf[date.Year][date.Month][date.Day] = cnd; // 将该日与0年1月1日的差保存
date.nextDay();// 计算下一天
cnd++; //计数器累加
} // while
int year1,month1,day1;
int year2,month2,day2;
while (scanf("%4d%2d%2d", &year1, &month1, &day1) != EOF){
scanf("%4d%2d%2d", &year2, &month2, &day2);
printf("%d\n",
Abs(buf[year1][month1][day1]-buf[year2][month2][day2]) + 1);
}
return 0;
}
3个优点:
1.使用预处理:判断闰年、提前计算出每天到0年1月1日的差
2.scanf的巧用,使用位数控制来区分出年月日
scanf
(
"%4d%2d%2d"
, &year1, &month1, &day1)
3.
int
buf[5001][13][32];
// 存放预处理的天数
这种大数组,应设为全局变量,main中的栈根本装不下,会溢出!
小结:
快速排序的基本用法,运算符重载;
printf输出参数;
scanf, 预处理,