ecnu18级程设实训第一次机考简易解题报告


愉快(并不)地考完了,看到LDY大佬的题解,决定学习一个,也来写一份解题报告。当然,这会是一个比较简易的版本,可能有所缺漏,敬请谅解。

此处是LDY大佬题解的传送门:

https://zhuanlan.zhihu.com/p/60305621

走过路过给个赞~

A. 恢复单词

单点时限: 2.0 sec

内存限制: 512 MB

学霸在背单词的时候发现单词的大小写混乱,而且可能参杂了0-9的数字和 %,+,&,#这四种特殊符号。请编写程序让单词恢复正常。要求处理后单词的首字母大写,且其余字母均为小写。

注意:单词虽然大小写混乱,但是字母间的顺序均正确。

例如:%sa+01t2urdAY,经过处理后为:Saturday

输入格式

混乱的单词s1, s1的长度<=100。

输出格式

去掉数字和特殊字符后的单词,单词首字母大写,其余字母小写。
s1中的数字
s1中的其它字符

样例

input

%sa+01t2urdAY

output

Saturday
012
%+

input

book

output

Book

提示

若对应内容不存在,则不用输出任何信息。

第一题考的是字符串的基本操作,用STL的string类可以说是事半功倍,如果用字符数组实现,大概要注意一下结尾的 ‘ \0 ‘。注意单词的大小写判断。还有提示里“任何信息”包括空格。

#include<bits/stdc++.h>//万能头文件
using namespace std;
int main(){
    string s1,word,num,other;
    int l,i;
    bool firLetter(false);//判断是否是第一个字母
    cin>>s1;
    l=s1.length();//获得s1的长度
    for(i=0;i<l;i++){
        if(s1[i]>=‘a‘&&s1[i]<=‘z‘||s1[i]>=‘A‘&&s1[i]<=‘Z‘){//如果是字母
            if(!firLetter&&s1[i]>=‘a‘)//是首字母且为小写
                s1[i]+=‘A‘-‘a‘;
            else if(firLetter&&s1[i]<‘a‘)//不说首字母且为大写
                s1[i]+=‘a‘-‘A‘;
            word+=s1[i];
            firLetter=true;    //接下去的都不是第一个字母
        }
        else if(s1[i]>=‘0‘&&s1[i]<=‘9‘)//是数字
            num+=s1[i];
        else other+=s1[i];//其他
    }
    if(word.size()) cout<<word<<endl;//小心不要输出多余的空格
    if(num.size()) cout<<num<<endl;
    if(other.size()) cout<<other<<endl;
    return 0;
} 

不再想一想吗?

B. 数位和

单点时限: 2.0 sec

内存限制: 512 MB

“数位和”是指:把一个整数的各位累加后的结果。
例如正整数 123456 的数位和是 1+2+3+4+5+6=21。
现在,请你帮忙计算一个整数 n 在 r 进制下的数位和,并用相应的进制输出结果。

输入格式

第 1 行:整数 T(1≤T≤10) 为问题数。

第 2 行:第一个问题的数据。包含两个正整数 n(1≤n≤2147483647) 和 r(2≤n≤16)。

第 3 ∽ T+1 行:后面问题的数据,格式与第一个问题相同。

输出格式

对于每个问题,输出一行问题的编号(0 开始编号,格式:case #0: 等),然后在一行中输出用 r 进制表示的十进制正整数 n转换成 r 进制后的数位和。

样例

input

2
123456 10
123456 2

output

case #0:
21
case #1:
110

提示

当r进制大于10时,用大写字母A-F表示大于10的数字。

例如:十进制数29转换为16进制为 1D,此时数位和为14,则正确的输出应为:E

两次进制转换即可,当然,好像有一次转换完成的办法。

#include<bits/stdc++.h>
using namespace std;
char apl[20]={‘0‘,‘1‘,‘2‘,‘3‘,‘4‘,‘5‘,
        ‘6‘,‘7‘,‘8‘,‘9‘,‘A‘,‘B‘,‘C‘,‘D‘,‘E‘,‘F‘};//进制转换用
void solve(){
    int num,i(0),r,sum(0);
    char ans[100000]={};
    cin>>num>>r;
    while(num){
        sum+=num%r;
        num/=r;
    }//第一次进制转换
    while(sum){
        ans[i]=apl[sum%r];
        i++;
        sum/=r;
    }//第二次进制转换
    while(--i>=0)//逆序输出
        cout<<ans[i];
    cout<<endl;
}
int main(){
    int t,i;
    cin>>t;
    for(i=0;i<t;i++) {
        printf("case #%d:\n",i);
        solve();
    }
    return 0;
} 

不再想一想吗?

C. 谁是第一名

单点时限: 2.0 sec

内存限制: 512 MB

为了知道哪些学生最优秀,考虑他们的三项主要课程(C Programming Language, Mathematics , English)成绩和平均成绩(平均成绩四舍五入取整),分别用C,M,E,A表示。写一个程序,对学生的四项成绩进行排序并输出每项成绩的第一名。程序的输入为学生的学号和三门课程成绩,不包含平均成绩。

输入格式

第 1 行:一个整数 T (1≤T≤10) 为问题数。

对于每组测试数据:

第 1 行:整数 n (1≤n≤100) ,表示学生的数量。

第 2 行~第 n+1 行:每行分别是一个学生的成绩信息,包含学号(长度为 11),三门课程C, M, E的成绩G(G为整数且0<G≤100),各项之间都有一个空格。

输出格式

对于每个问题,输出一行问题的编号(0 开始编号,格式:case #0:等),然后分别输出A,C,M,E各项成绩中排名第一的学生的学号。当成绩并列第一时按按照学号的字典序顺序输出。

样例

input

2
5
10185101101 98 85 90
10185101102 98 95 88
10185101103 82 87 94
10185101104 91 91 91
10185101105 85 90 90
2
10185101103 82 87 94
10185101104 91 91 91

output

case #0:
A:
10185101102
C:
10185101101
10185101102
M:
10185101102
E:
10185101103
case #1:
A:
10185101104
C:
10185101104
M:
10185101104
E:
10185101103

提示

注意A(平均成绩)四舍五入取整数。

一道非常裸的排序题,一波STLsort解决之,注意A是取整数,如果用double反而不能通过。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct stu{//学生结构体
    int c,m,e,a;
    ll id;
};
bool cmpa(stu a,stu b){//比较函数
    if(a.a!=b.a) return a.a>b.a;
    return a.id<b.id;
}
bool cmpc(stu a,stu b){
    if(a.c!=b.c) return a.c>b.c;
    return a.id<b.id;
}
bool cmpm(stu a,stu b){
    if(a.m!=b.m) return a.m>b.m;
    return a.id<b.id;
}
bool cmpe(stu a,stu b){
    if(a.e!=b.e) return a.e>b.e;
    return a.id<b.id;
}
void solve(){
    int n,i;
    stu stud[105];
    cin>>n;
    for(i=0;i<n;i++){
        scanf("%lld%d%d%d",&stud[i].id,
        &stud[i].c,&stud[i].m,&stud[i].e);
        stud[i].a=double(stud[i].c+stud[i].m+stud[i].e)/3+0.49;
    }

    sort(stud,stud+n,cmpa);
    cout<<"A:"<<endl<<stud[0].id<<endl;
    i=1;
    while(i<n&&stud[i].a==stud[0].a){//同时第一的输出,注意不要越界
        cout<<stud[i].id<<endl;
        i++;
    }

    sort(stud,stud+n,cmpc);
    cout<<"C:"<<endl<<stud[0].id<<endl;
    i=1;
    while(i<n&&stud[i].c==stud[0].c){
        cout<<stud[i].id<<endl;
        i++;
    }

    sort(stud,stud+n,cmpm);
    cout<<"M:"<<endl<<stud[0].id<<endl;
    i=1;
    while(i<n&&stud[i].m==stud[0].m){
        cout<<stud[i].id<<endl;
        i++;
    }

    sort(stud,stud+n,cmpe);
    cout<<"E:"<<endl<<stud[0].id<<endl;
    i=1;
    while(i<n&&stud[i].e==stud[0].e){
        cout<<stud[i].id<<endl;
        i++;
    }
    return ;
}
int main(){
    int t,i;
    cin>>t;
    for(i=0;i<t;i++) {
        printf("case #%d:\n",i);
        solve();
    }
    return 0;
} 

不再想一想吗?

D. 记忆碎片

单点时限: 2.0 sec

内存限制: 512 MB

在徒弟的记忆中,自入门以来,师父的身影似乎一直陪伴在自己身旁。
多年后,徒弟只剩下零碎的记忆片段,不过每段记忆片段却十分的清晰,并且能很明确的说出这段记忆发生在哪一段时间内。
徒弟很想知道自己和师父在一起一共有多少日子,请帮他解决上述问题。

输入格式

包含一个整数N
接下来的N行,每行包含两个不同的整数s, t,表示一段记忆碎片发生的起始时间s和结束时间t。

数据约束
对于60%的数据,N<=500,0<=s<=t<=1000
对于100%的数据,N<=5000, 0<=s<=t<=5000000

输出格式

一个整数,表示徒弟能回忆起的和师父在一起的日子总数

样例

input

3
100 200
150 300
470 471

output

203

提示

对于输入样例:
3
100 200
150 300
470 471



解释:
记忆中和师父在一起的日子为[100,300]和[470,471],一共203天。


这道题可以说是一道非常经典的贪心题了。

如果不说贪心,可以暴力模拟这个过程,开一个数组,对于每个区间内的数置一,最后把整个区间扫一遍。

显然这样只能过60%。那贪心是怎么操作的呢?我们首先可以看到,对暴力法,后期制约时间的主要因素是遍历区间的每个点,而相比之下更快速的办法是,对每个区间的end-start+1累加,但这样可能会重复计数。所以我们先对所有区间按区间头升序排列,然后开始维护一个当前区间,如果下一个区间的start比当前区间的end值更小,意味着下一个区间和当前区间是重合的,把下一个区间合并入当前区间,否则结算当前区间的长度,并把下一个区间作为新的当前区间。

注意最后一个区间需要特判。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct p{//区间头尾
    int start,end;
};
bool cmp(p a,p b){
    if(a.start!=b.start) return a.start<b.start;
    return a.end<b.end;
}
int main(){
    int n,i,start,end;
    ll ans(0);
    p part[5005];
    cin>>n;
    for(i=0;i<n;i++) scanf("%d%d",&part[i].start,&part[i].end);
    sort(part,part+n,cmp);
    start=part[0].start;
    end=part[0].end;
    for(i=1;i<n;i++){
        if(part[i].start>end){//不能合并
            ans+=end-start+1;//注意+1
            start=part[i].start;
            end=part[i].end;
        }
        else
            end=max(end,part[i].end);//合并

    }
    ans+=end-start+1;//最后一个区间的特判
    cout<<ans<<endl;
    return 0;
} 

不再想一想吗?

E. 徒弟的下山之路

单点时限: 2.0 sec

内存限制: 512 MB

终于到了出师的日子,徒弟需要从山顶的纯阳宫找一条花费最少时间的下山之路。
这座山用一个三角形来表示,从山顶依次向下有n层,第i层有i个可移动的位置,出口在最下层的左边。例如有一座5层的山:
        1 
      3  2 
    4  5  6 
  9  1  7  8 
1  1  4  5  6

此示例中出口为最下层最左边的1所在位置。山上每个数字代表徒弟路过这个位置需要花费的时间,徒弟下山总时间为路径上数字之和。

徒弟每次可以往左、右、左下、右下四个方向移动,例如徒弟位于第3层的数字5时可以向左走到4,向右走到6;也可以向左下走到1,向右下走到7;
又如徒弟位于第3层的数字6时,可以向左走到5,无法向右;也可以向左下走到7,向右下走到8;

输入格式

第一行一个整数n,表示山的高度
接下来n行,第i行有i个整数,表示徒弟经过这个位置需要的时间(路过每个位置花费的时间不超过10)。

数据约束
对于20%的数据,n=4
对于60%的数据,n<=10
对于100%的数据,n<=1000

输出格式

徒弟下山需要花费的最少时间

样例

input

5
1
3 2
4 5 6
9 1 7 8
1 1 4 5 6

output

11

提示

徒弟下山花费的时间为1+3+4+1+1+1=11

一眼看过去感觉就是数字三角形,再仔细一看发现可以向四个方向走......好吧,动态转移方程挺好写的,dp[i,j]=map[i,j]+max(dp[i,j-1],dp[i,j+1],dp[i+1,j],dp[i+1,j+1],但实现起来发现略麻烦。转换一下思路,可以用bfs解决,开一个队列,对队首可以到达的路径枚举,更新最短的路径,并把有更新的放入队中。写完发现这不就是Dijkstra吗?(捂脸

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int mapping[1005][1005],dp[1005][1005];
int directX[5]={0,0,1,1};
int directY[5]={-1,1,0,1};//方向数组
struct point{
    int x,y,time;
}x;
int main(){
    int n,i,j;
    cin>>n;
    for(i=1;i<=n;i++)
    for(j=1;j<=i;j++) scanf("%d",&mapping[i][j]);

    x.x=x.y=1;
    x.time=dp[1][1]=mapping[1][1];
    queue<point> que;
    que.push(x);
    while(!que.empty()){//bfs
        x=que.front();
        que.pop();
        if(x.time>dp[x.x][x.y]) continue;
        for(i=0;i<4;i++){
            x.x+=directX[i];
            x.y+=directY[i];
            x.time+=mapping[x.x][x.y];//新结点
            if(mapping[x.x][x.y]&&(dp[x.x][x.y]>x.time||!dp[x.x][x.y])){//(没有越界&&(可以更新||没更新过))
                que.push(x);
                dp[x.x][x.y]=x.time;
            }
            x.time-=mapping[x.x][x.y];
            x.x-=directX[i];
            x.y-=directY[i];    //还原为原结点
        }
    }

    cout<<dp[n][1]<<endl;
    return 0;
} 

不再想一想吗?

原文地址:https://www.cnblogs.com/wengsy150943/p/10624942.html

时间: 2024-10-09 07:02:14

ecnu18级程设实训第一次机考简易解题报告的相关文章

网络实训——服务器应用系统的实践

1 设计内容与设计要求 1.1设计内容 课题10:服务器应用系统的实践 服务器指一个管理资源并为用户提供服务的计算机软件,通常分为文件服务器.数据库服务器和应用程序服务器.运行以上软件的计算机或计算机系统也被称为服务器. 实训内容: (1)搭建简单的三层局域网环境 (2)部署Web服务器,并创建简单网页 (3)部署DNS服务器,并对Web服务器做域名解析 (4)部署DHCP服务器,对终端电脑实现动态IP获取 (5)部署FTP服务器,使终端电脑能访问并存储文件 (6)完成测试并写出详细课设报告 1

HTML+CSS网站实训项目总结

  学完HTML+CSS,迎来的最重要的是网站实训和答辩的准备.          第一次的项目分配,因剪刀石头布的手气,得到第二名的机会,却实在不怎么了解各个网站,(当然除了最熟悉的淘宝),选择了组员的要求——国美在线.          国美在线,是国美电器唯一官方商城,中国领先的专业家电网购平台.          这是第一次做的团队小项目,也是第一次以组长的身份和组员进行磨合和合作.          于组长的身份,这是最大的感受除了开始拿到项目的时候的小小激动,就是怕分工不恰当和组织不

实训任务05 MapReduce获取成绩表的最高分记录

实训任务05  MapReduce获取成绩表的最高分记录 实训1:统计用户纺问次数 任务描述: 统计用户在2016年度每个自然日的总访问次数.原始数据文件中提供了用户名称与访问日期.这个任务就是要获取以每个自然日为单位的所有用户访问次数的累加值.如果通过MapReduce编程实现这个任务,首先要考虑的是,Mapper与Reducer各自的处理逻辑是怎样的:然后根据处理逻辑编写出核心代码:最后在Eclipse中编写完整代码,编译打包后提交给集群运行. 分析思路和逻辑 (1)       输入/输出

实训团队心得(1)

这次实训我们团队做的是J2EE项目,在这次项目中,我们需要搭建的是一个基于SSH2框架的关于学校教室资源分配的系统.在这次项目中,我第一次尝试担当项目开发团队的负责人. 由于团队是第一次进行合作,因此在各个方面都显得不太成熟,如组织.讨论等等方面.下面是自己在担当负责人的一些心得,以备后用: 1)关于团队学习 在这次项目中,团队在遇到J2EE的相关知识时,有点慌乱,因为大家都不知道应该从哪方面对J2EE这种了解过得技术进行学习.结果在项目准备阶段中,大家都是在研究J2EE的结果以及相关配置.结果

c++课程实训 银行储蓄系统

基本要求:定义了用户类(User)和银行类(Bank),用成员函数实现各种功能,多文件组织程序.能用文本文件存取数据(如演示样例中给出的技术): 拓展方向: 序号 加分项目 细       则 1 改变Bank类中用户信息的存储方式 用对象的指针数组存储(User *user[upNum]) 或者用动态数组(User *users.空间用new分配) 2 功能扩充 按银行实际业务的要求,添加User类中的数据成员,可以记录身份证号.家庭住址等信息,并在相关业务中使用这些数据. 记录用户的每一笔业

2015-1-18实训结束

大三实训  JAVA和数据库的使用,三个人一组,我这一组分到的题目是“房产管理系统” 项目要求: 项目目标:系统应能对房产信息.住户基本信息(户主.家庭成员)等进行管理.所有信息能方便的增加.修改.删除等操作.至少应该实现系统功能:系统设置,包括信息项目需要的类别.代码等数据维护:房产信息中的小区.楼宇.住房等信息的维护:住户信息管理,户主信息.家庭成员信息维护:查询模块包括各种信息的查询.统计等. 实训一共两个星期多点的时间,由于我需要帮助别的组的同学,所以我用了3-5天的时间简单了完成了我这

安卓实训第九天---Activity的复习以及在Onstart里设置网络连接

今天,首先对Activity的生命周期进行复习: (下面的截图部分是借鉴自赵雅智老师的博客...) Activity的完整生命周期自第一次调用onCreate()开始,直至调用onDestroy()为止.Activity在onCreate()中设置所有"全局"状态以完成初始化,而在onDestroy()中释放所有系统资源.例如,如果Activity有一个线程在后台运行从网络下载数据,它会在onCreate()创建线程,而在 onDestroy()销毁线程. 刚进入activity: 按

【CC2530入门教程-增强版】基础技能综合实训案例(基础版)-终端源码

[CC2530入门教程-增强版]基础技能综合实训案例(基础版)-终端源码 广东职业技术学院 欧浩源 一.关于硬件电路 关于这个综合实训案例,具体需求详见<[CC2530入门教程-增强版]基础技能综合实训案例(基础版)-题目需求>. 我自己实在"全国职业院校技能大赛--物联网技术应用赛项"的Zigbee模块上实现的.该模块的电路应该和TI公司官方评估板的推荐电路差不多,我想现在市面上很多开发板也是参考这样的电路设计,只要您使用的开发板上有LED灯.按键输入.串口输出和一路A/

.NET MVC4 实训记录之五(访问自定义资源文件)

.Net平台下工作好几年了,资源文件么,大多数使用的是.resx文件.它是个好东西,很容易上手,工作效率高,性能稳定.使用.resx文件,会在编译期动态生成已文件名命名的静态类,因此它的访问速度当然是最快的.但是它也有个最大的缺点,就是修改资源文件后,项目必须重新编译,否则修改的资源不能被识别.这对于维护期的工作来讲,非常麻烦.尤其是已经上线的项目,即使是修改一个title的显示,也需要停掉项目.由于本人做了好几年的维护,应该是从工作到现在,一直没有间断过的做维护项目,因此深受其害!必须找到一个