Java 在Word中嵌入多媒体(视频、音
554 2023-04-03 03:33:31
结构体概念:可以把各种类型的数据放在一起,形成新的数据类型。
如何定义:关键字 struct:
格式:struct 结构名{ 数据类型 变量名1; 数据类型 变量名2;};
如:定义一个学生,他有姓名,年龄,语文成绩,数学成绩,英语成绩
struct T{ string name; int age; int score1,score2,score3;}stu[N];
访问结构体中的信息,通过 ”.”来访问
stu[i].name = "张三";stu[i].age = 13;stu[i].score1 = 100;stu[i].score2 = 90;stu[i].score3 = 80;
结构体成员函数:行为
struct T{ string name; int age; int score1,score2,score3; //属性 int sum(){ //行为 return score1+score2+score3; }}stu[N];
我们可以将它(T)看做一类人,而 stu[100] 就是这一类人中的100个人,他们具有相似的属性(name,age,score)和行为(sum())
结构体一般在泛型排序结合贪心的题型上使用,如:
给出5个人的信息(包括姓名,年龄,三门学科分数),现在让你按照三门学科总分进行降序排序,如果总分相同则年龄小的在前面。
#include<iostream>#include<string>#include<algorithm>using namespace std;const int N=100, n=5;struct T{ string name; int age; int score1,score2, score3; int sum(){ return score1+score2+score3; }}stu[N];bool cmp(T a, T b){ // 如果总分不同,则按照总分升序排序 if(a.sum()!=b.sum()) return a.sum()>b.sum(); return a.age<b.age;//总分相同,按照年龄小大排序}/*输入样例:a 11 100 100 100b 22 80 90 90c 33 90 90 90d 44 80 80 80e 55 90 80 80*/int main(){ for(int i=0; i<n; i++){ cin>>stu[i].name>>stu[i].age>>stu[i].score1>>stu[i].score2>>stu[i].score3; } sort(stu, stu+n, cmp); for(int i=0; i<n; i++){ cout<<stu[i].name<<" "<<stu[i].age<<" "<<stu[i].sum()<<endl; } return 0;}
【题目描述】现有 N(N≤1000) 名同学参加了期末考试,并且获得了每名同学的信息:
姓名(不超过 8 个字符的字符串,没有空格)、语文、数学、英语成绩(均为不超过 150 的自然数)。
总分最高的学生就是最厉害的,请输出最厉害的学生各项信息(姓名、各科成绩)。
如果有多个总分相同的学生,输出靠前的那位。
输入格式:先输入数字 n,表示有n个学生,再输入n行,每行包含学生姓名,语文、数学、英语成绩
输出格式:最厉害的学生各项信息(姓名、语文、数学、英语成绩)
输入样例:
3senpai 114 51 4lxl 114 10 23fafa 51 42 60
输出样例:
senpai 114 51 4
题解:
#include<iostream>#include<string>#include<algorithm>using namespace std;const int N=1e3;struct T{ string name; int a,b,c,id; int sum(){ return a+b+c; }}stu[N];bool cmp(T a, T b){ // 如果总分不同,则按照总分降序排序 if(a.sum()!=b.sum()) return a.sum() > b.sum(); return a.id < b.id; //总分相同,按照学号升序排序}int main() { int n; cin>>n; for(int i=0; i<n; i++){ stu[i].id = i; cin>>stu[i].name>>stu[i].a>>stu[i].b>>stu[i].c; } sort(stu, stu+n, cmp);//自定义排序方式 int i=0; cout<<stu[i].name<<" "<<stu[i].a<<" "<<stu[i].b<<" "<<stu[i].c; return 0;}
【题目描述】现有 N(N≤1000) 名同学,每名同学需要设计一个结构体记录以下信息:
学号(不超过 100000 的正整数)、学业成绩和素质拓展成绩(分别是 0 到 100 的整数)、综合分数(实数)。
每行读入同学的姓名、学业成绩和素质拓展成绩,并且计算综合分数(分别按照 70% 和 30% 权重累加),存入结构体中。
还需要在结构体中定义一个成员函数,返回该结构体对象的学业成绩和素质拓展成绩的总分。
然后需要设计一个函数,其参数是一个学生结构体对象,判断该学生是否“优秀”。
优秀的定义是学业和素质拓展成绩总分大于140 分,且综合分数不小于 80 分。
输入格式:第一行一个整数 N,接下来 N 行,每行 3 个整数,依次代表学号、学业成绩和素质拓展成绩。
输出格式:N 行,如果第 i 名学生是优秀的,输出 Excellent
,否则输出 Not excellent
。
输入样例:
41223 95 591224 50 71473 32 451556 86 99
输出样例:
ExcellentNot excellentNot excellentExcellent
题解:
#include<iostream>#include<algorithm>using namespace std;struct T{ int id; int s1,s2;//学业成绩和素质拓展成绩 double s3;//综合分数(实数) double sum1(){//学业成绩和素质拓展成绩的总分 return s1+s2; }}stu[1000];int main(){ int n; cin>>n; for(int i=0; i<n; i++){ cin>>stu[i].id>>stu[i].s1>>stu[i].s2; stu[i].s3=0.7*stu[i].s1+0.3*stu[i].s2; } for(int i=0; i<n; i++){ if(stu[i].sum1()>140 && stu[i].s3>=80){//优生条件 cout<<"Excellent"<<endl; }else{ cout<<"Not Excellent"<<endl; } } return 0;}
【题目描述】某小学最近得到了一笔赞助,打算拿出其中一部分为学习成绩优秀的前5名学生发奖学金。
期末,每个学生都有3门课的成绩:语文、数学、英语。
先按总分从高到低排序,
如果两个同学总分相同,再按语文成绩从高到低排序,
如果两个同学总分和语文成绩都相同,那么规定学号小的同学 排在前面,
这样,每个学生的排序是唯一确定的。
任务:先根据输入的3门课的成绩计算总分,然后按上述规则排序,最后按排名顺序输出前五名名学生的学号和总分。
注意,在前5名同学中,每个人的奖学金都不相同,因此,你必须严格按上述规则排序。
例如,在某个正确答案中,如果前两行的输出数据(每行输出两个数:学号、总分) 是:
7 2795 279
这两行数据的含义是:总分最高的两个同学的学号依次是7号、5号。
这两名同学的总分都是 279 (总分等于输入的语文、数学、英语三科成绩之和) ,但学号为7的学生语文成绩更高一些。
如果你的前两名的输出数据是:
5 2797 279
输入格式:
共 n+1 行,第 1 行为一个正整数 n(n≤300),表示该校参加评选的学生人数。
第 2 到 n+1 行,每行有 3 个用空格隔开的数字,每个数字都在 0到 100之间。
第 j 行的 3 个数字依次表示学号为 j-1 的学生的语文、数学、英语的成绩。
每个学生的学号按照输入顺序编号为 1~n(恰好是输入数据的行号减 1)。
所给的数据都是正确的,不必检验。
输出格式:共 5行,每行是两个用空格隔开的正整数,依次表示前5名学生的学号和总分。
输入样例:
690 67 8087 66 9178 89 9188 99 7767 89 6478 89 98
输出样例:
6 2654 2643 2582 2441 237
题解:
#include<iostream>#include<algorithm>using namespace std;const int N=310;struct T{ int s1,s2,s3;//语文,数学,英语成绩 int id; //学号 int sum(){//总分 return s1+s2+s3; }}stu[N];bool cmp(T a, T b){ if(a.sum()!=b.sum()) return a.sum()>b.sum();//总分降序排列 if(a.s1!=b.s1) return a.s1>b.s1;//语文成绩降序排列 return a.id<b.id;//学号升序排列}int main() { int n; cin>>n; for(int i=0; i<n; i++){ cin>>stu[i].s1>>stu[i].s2>>stu[i].s3; stu[i].id = i+1;//学号 } sort(stu, stu+n, cmp);//自定义排序 for(int i=0; i<5; i++){//前5名 cout<<stu[i].id<<" "<<stu[i].sum()<<endl; } return 0;}
【题目描述】cjf 君想调查学校OI组每个同学的生日,并按照从大到小的顺序排序。
输入格式:有2行,第1行为OI组总人数n,第2行至第n+1行分别是每人的姓名s、出生年y、月m、日d
输出格式:有n行,即n个生日从大到小同学的姓名(如果有两个同学生日相同,输入靠后的同学先输出)
输入样例:
3Yangchu 1992 4 23Qiujingya 1993 10 13Luowen 1991 8 1
输出样例:
LuowenYangchuQiujingya
数据范围:1<n<100,length(s)<20
题解:
#include<iostream>#include<string>#include<algorithm>using namespace std;struct T{ string name; int y,m,d;//year,month,day int id; //输入先后顺序}stu[110];bool cmp(T a, T b){ if(a.y!=b.y) return a.y<b.y;//如果年份不同,按年份升序排序 if(a.m!=b.y) return a.m<b.m;//如果月份不同,按月份升序排序 if(a.d!=b.d) return a.d<b.d;//如果天数不同,按天数升序排序 return a.id>b.id; //按输入顺序,逆序排序}int main() { int n; cin>>n; for(int i=0; i<n; i++){ cin>>stu[i].name>>stu[i].y>>stu[i].m>>stu[i].d; stu[i].id = i; } sort(stu, stu+n, cmp);//自定义排序规则 for(int i=0; i<n; i++){ cout<<stu[i].name<<endl; } return 0;}
【题目描述】世博会志愿者的选拔工作正在 A 市如火如荼的进行。
为了选拔最合适的人才,AA市对所有报名的选手进行了笔试,笔试分数达到面试分数线的选手方可进入面试。
面试分数线根据计划录取人数的150%划定,即如果计划录取m名志愿者,
则面试分数线为排名第m×150%(向下取整)名的选手的分数,而最终进入面试的选手为笔试成绩不低于面试分数线的所有选手。
现在就请你编写程序划定面试分数线,并输出所有进入面试的选手的报名号和笔试成绩。
输入格式:
第一行,两个整数 n,m(5≤n≤5000,3≤m≤n),中间用一个空格隔开,其中 n表示报名参加笔试的选手总数,m表示计划录取的志愿者人数。输入数据保证 m×150%向下取整后小于等于 n。
第二行到第 n+1 行,每行包括两个整数,中间用一个空格隔开,分别是选手的报名号 k(1000≤k≤9999)和该选手的笔试成绩 s(1≤s≤100)。数据保证选手的报名号各不相同。
输出格式:
第一行,有2个整数,用一个空格隔开,第一个整数表示面试分数线;第二个整数为进入面试的选手的实际人数。
从第二行开始,每行包含2个整数,中间用一个空格隔开,分别表示进入面试的选手的报名号和笔试成绩,按照笔试成绩从高到低输出,如果成绩相同,则按报名号由小到大的顺序输出。
输入样例:
6 31000 903239 882390 957231 841005 951001 88
输出样例:
88 51005 952390 951000 901001 883239 88
题解:
#include<iostream>#include<algorithm>#include<cmath>using namespace std;const int N=1e4;struct T{ int k,s;}stu[N];bool cmp(T a, T b){ if(a.s!=b.s) return a.s>b.s;//按成绩降序排列 return a.k<b.k;//按成绩升序排列}int main(){ int n,m; cin>>n>>m; int num=floor(m*1.5);//参与面试的人数 for(int i=1; i<=n; i++){ cin>>stu[i].k>>stu[i].s; } sort(stu+1, stu+n+1, cmp); int score=0, ans=0;//最后进入面试的分数,人数 for(int i=1; i<=n; i++){ if(i<=num || stu[i].s==score){ ans++; score=stu[i].s; }else{ break; } } cout<<score<<" "<<ans<<endl; for(int i=1; i<=ans; i++){ cout<<stu[i].k<<" "<<stu[i].s<<endl; }return 0;}
【题目描述】 某校的惯例是在每学期的期末考试之后发放奖学金。发放的奖学金共有五种,获取的条件各自不同:
院士奖学金,每人8000元,期末平均成绩高于80分(>80),并且在本学期内发表1篇或1篇以上论文的学生均可获得;
五四奖学金,每人4000元,期末平均成绩高于85分(>85),并且班级评议成绩高于80分(>80)的学生均可获得;
成绩优秀奖,每人2000元,期末平均成绩高于90分(>90)的学生均可获得;
西部奖学金,每人1000元,期末平均成绩高于85分(>85)的西部省份学生均可获得;
班级贡献奖,每人850元,班级评议成绩高于80分(>80)的学生干部均可获得;
只要符合条件就可以得奖,每项奖学金的获奖人数没有限制,每名学生也可以同时获得多项奖学金。
例如姚林的期末平均成绩是87分,班级评议成绩82分,同时他还是一位学生干部,那么他可以同时获得五四奖学金和班级贡献奖,奖金总数是4850元。
现在给出若干学生的相关数据,请计算哪些同学获得的奖金总数最高(假设总有同学能满足获得奖学金的条件)。
输入格式:
第一行是1个整数N(1≤N≤100),表示学生的总数。
接下来的N行每行是一位学生的数据,从左向右依次是姓名,期末平均成绩,班级评议成绩,是否是学生干部,是否是西部省份学生,以及发表的论文数。
姓名是由大小写英文字母组成的长度不超过20的字符串(不含空格);
期末平均成绩和班级评议成绩都是0到100之间的整数(包括0和100);
是否是学生干部和是否是西部省份学生分别用1个字符表示,Y表示是,N表示不是;
发表的论文数是0到1010的整数(包括0和10)。每两个相邻数据项之间用一个空格分隔。
输出格式:
包括3行,第1行是获得最多奖金的学生的姓名。
第2行是这名学生获得的奖金总数。如果有两位或两位以上的学生获得的奖金最多,输出他们之中在输入文件中出现最早的学生的姓名。
第3行是这N个学生获得的奖学金的总数。
输入样例:
4YaoLin 87 82 Y N 0ChenRuiyi 88 78 N Y 1LiXin 92 88 N N 0ZhangQin 83 87 Y N 1
输出样例:
ChenRuiyi900028700
题解:这道题就是使用结构体来排序,并且多了一下判断条件,需要注意细节
#include<iostream>#include<string>#include<algorithm>using namespace std;const int N=1e2+5; //定义常量Nstruct T{ int id; string name; int score1,score2,num; char flag1,flag2; int money(){ int sum=0; if(score1>80 && num>=1) sum+=8000; if(score1>85 && score2>80) sum+= 4000; if(score1>90) sum += 2000; if(score1>85 && flag2=='Y') sum += 1000; if(score2>80 && flag1=='Y') sum += 850; return sum; }}stu[N];bool cmp(T a, T b){//自定义排序规则 if(a.money() !=b.money()){ return a.money() > b.money();//获得奖学金最多的同学在前 } return a.id < b.id;//按学号升序排序}int main(){ int n; cin>>n; for(int i=0; i<n; i++){ cin>>stu[i].name>>stu[i].score1 >>stu[i].score2>>stu[i].flag1 >>stu[i].flag2>>stu[i].num; stu[i].id = i; } sort(stu, stu+n, cmp);//自定义排序,注意下标 int sum=0; for(int i=0; i<n; i++){ sum += stu[i].money();//奖学金总数 } cout<<stu[0].name<<endl<<stu[0].money()<<endl; cout<<sum<<endl; return 0;}
构造函数是在对象创建时候进行对象初始化的一种特殊函数。
不需要手动调用,当我们创建对象时,系统会自动调用。
#include<iostream>#include<cstdio>using namespace std;struct T{ int u,v,w; T(){} // 无参数构造函数 T(int a,int b,int c){// 有参数构造函数 u=a, v=b, w=c; } void show(){ printf("u=%2d, v=%2d, w=%2d\n",u,v,w); }};int main(){ T t1; // 调用无参构造函数赋值,随机值 T t2(1,2,3); // 调用有参构造函数赋值 t1.show(); t2.show(); return 0;}
这个其实主要对于数据测试和竞赛中有用,平常用不上,但是比赛又必须要使用
#include<iostream>#include<cstdio>using namespace std;int main() { //替代我们的手动输入,将文件中内容读入输入流中 freopen("输入文件名", "r", stdin); //将输出流中的数据写入文件中 freopen("输出文件名", "w", stdout); //正常的执行程序 long long a,b; cin>>a>>b; cout<<a+b<<endl; fclose(stdin); //关闭输入流 fclose(stdout); //关闭输出流 return 0;}
在 windows 系统上可以不写fclose,系统会自动关闭,
但是 Linux 系统上如果不写会出现问题,无法正常关闭或文件保存出现问题,OI系列评测均是在Linux系统上进行的,所以一定要手动关闭。
其实用这个来代替我们的手动输入是比较方便的,大家可以多习惯这样的用法。
举例:【题目描述】输入a,b, 输出a+b的结果(0<=a, b<=2^31)。
最后应该提交的的源文件,应当命名为:ab.cpp(注意大小写),并存放如下内容
#include<iostream>#include<cstdio>using namespace std;int main() { freopen("ab.in", "r", stdin); //读入文件 freopen("ab.out", "w", stdout); //输出文件 long long a,b; cin>>a>>b; cout<<a+b; fclose(stdin); //关闭输入流 fclose(stdout); //关闭输出流 return 0;}
这样程序就会从文件 ab.in
里面读取前两个数据,分别赋值给a,b,从而替代我们手动输入的过程。
并且会将a+b的结果保存到文件 ab.out
里面,就不会在控制台窗口输出(也就是小黑方框)。
另外注意,OI(CSP/NOIP/..)系列的比赛中源文件提交有格式要求,注意官网信息,这里大概说明几点: