2018-2019赛季多校联合新生训练赛第六场补题与题解(中石油)

**总结:**这场比赛是我成绩最好的一次,也是打比赛这么多以来第一次拿到银牌(40名)可能因为昨天是我弟弟的生日把哈哈哈哈有他在家里保佑我进银牌区,这场比赛怎么说呢,考点和难度感觉都比上次要高了很多,而且感觉考点非常的生僻,考了个四舍五入,学了一个新函数round 学完这个函数以后感觉以后遇到四舍五入的题目都不是问题了! 下面开始吧!
问题 A: 价钱统计

这题到目前为止我会了三种方法:第一种是我自己ac的方法,感觉纯属碰巧了,可能这次的测试样例比较少,不然也过不了,我经过大量的测试发现在后面加一个0.04就可以解决四舍五入的问题!(这当然不是正解) 代码:

#include
using namespace std;
int main() {
  double a,b,c,d;
  cin>>a>>b>>c>>d;
  double sum=0;
  sum+=a*1.2+b*3.5+c*4.5+d*5.0;
  printf("%.1f\n%.1f\n%.1f\n%.1f\n%.1f",a*1.2+0.04,b*3.5+0.04,c*4.5+0.04,d*5.0+0.04,sum+0.04);
}

下面是第二种方法和第三种的方法,介绍一个新函数:round 感觉这个函数特别的好用,如果是个位数四舍五入的话,直接把数套进去就行了 如果是这题这样的,直接乘以10外面再除以10一样解决问题。

#include
using namespace std;
double trans(double a)
{
  a*=10;
  a+=0.5;
  a=int(a);
  a/=10;
  return a;
}
int main() {
  double a;
  cin>>a;
  cout<<round(a*10)/10<<endl;
  cout<<trans(a);
}

2018-2019赛季多校联合新生训练赛第六场补题与题解(中石油)_第1张图片
这里发现,这两种方法得出的答案是一样的,对于本题来说,直接每次都使用一次函数就ok了 具体细节就不多写了。
问题 B: 打印图形

题目描述

由键盘输入一个大写字母(A到Z中的任意一个),输出如下图所示由相关大写字母组成的图形。所输入的字母一定为输出文件的第一个字符(位于图形的左上角),其余部分的字母构成规律和分布由样例给出。

输入

只有一行,仅为一个大写字母。

输出

包含一个如样例所示的图形。注意图形的行数与输入的字母有关,图形中第一行最左侧一定是你输入的那个字母。

样例输入
复制样例数据 C

样例输出
CBAAB
” BAA
“”“” A

由于csdn自动左对齐,所以只能这样,下面贴一张截图:
2018-2019赛季多校联合新生训练赛第六场补题与题解(中石油)_第2张图片
这题卡了我有一段时间,后来找到规律以后才做出来的,是我最后a的一道题。。今天又出了一道这样的题,感觉找不到规律的话不太好做啊,不过找到规律就简单了!
这里还用到了强制类型转换

#include
using namespace std;
int main() {
  char c;
  cin>>c;
  int a=c-'A'+1;
  for(int i=0;i<a;i++) {
    for(int j=0;j<i;j++)
    cout<<" ";
    for(int k=i;k<a;k++)
    cout<<char(c-k);
    for(int l=a-1;l>=i+1;l--)
    cout<<char(c-l);
    cout<<endl;
  }
}

问题 C: 数列计算I

题目描述

有一列数是:4/7, 7/11, 11/18, 18/29, 29/47, 47/76 „„请找出这个数列的规律,编写程序计算并输出这个数列的第 N 项(要求是分数形式),并计算这个数列的前 N 项和(结果四舍五入保留两位小数)。(其中:3≤N≤30)。

输入

只有一行,包含1个符合题目要求的正整数N。

输出

共有两行。
第一行如样例中的一个特定格式的分数表示这个数列的第N项;
第二行仅包含一个数表示这个数列的前N项的和。

样例输入
复制样例数据 6

样例输出
47/76
3.68

这题也是一道基础题,算是一道递推题,刚开始在for循环里面因为分子改变还卡了我一下,后来手动调试以后才过的 这题注意一下数据很大,不能直接用cout 下面是一段错误示范

#include
using namespace std;
int main() {
  int n;
  cin>>n;
  double fz=4;
  double fm=7;
  double sum=0;
  double ans=fz/fm;
  sum+=ans;
  double a;
  for(int i=0;i<n-1;i++) {
    a=fz;
    fz=fm;
    fm+=a;
    ans=fz/fm;
    sum+=ans;
  }
  cout<<fz<<"/"<<fm<<endl;
  printf("%.2f",sum);
}

AC代码:

#include
using namespace std;
int main() {
  int n;
  cin>>n;
  double fz=4;
  double fm=7;
  double sum=0;
  double ans=fz/fm;
  sum+=ans;
  double a;
  for(int i=0;i<n-1;i++) {
    a=fz;
    fz=fm;
    fm+=a;
    ans=fz/fm;
    sum+=ans;
  }
  printf("%.0lf/%.0lf\n",fz,fm);
  printf("%.2f",sum);
}

问题 D: 单词排序

题目描述

小红学会了很多英语单词,妈妈为了帮小红加强记忆,拿出纸、笔,把n个单词写在纸上的一行里,让小红看几秒钟后,将这张纸扣在桌子上。妈妈问小红:你能否将这些n个单词按照字典排列的顺序,从小到大写出来?小红按照妈妈的要求写出了答案。现在请你编写程序帮助妈妈检查小红的答案是否正确。注意:所有单词都由小写字母组成,开头字母全都不同,单词两两之间用一个空格分隔。

输入

有两行:第一行仅包含一个正整数n(0 单个单词长度不超过10。

输出

仅有一行:针对妈妈写出的单词,按照字典排列的顺序从小到大排成一行的结果,单词两两之间用一个空格分隔。

样例输入
复制样例数据 4
city boy tree student

样例输出
boy city student tree

很简单的一道排序题,不多说 代码:

#include
using namespace std;
int main() {
  int n;
  cin>>n;
  string a[100];
  for(int i=0;i<n;i++)
  cin>>a[i];
  sort(a,a+n);
  for(int i=0;i<n;i++) {
    if(i==n-1)
    cout<<a[i];
    else
    cout<<a[i]<<" ";
  }
}

问题 E: 评奖

题目描述

东东所在的班级有 N 名同学,期末考试进行了数学、语文、英语、地理四门功课的测试。班主任要将这 N 名学生中总分前三名确定为本学期的“学习小标兵”。现在给出这 N 名学生的姓名和各科成绩,请你编程找到总分前三名,并依次输出他们的姓名。所给数据不会有总分相同的情况。

输入

共有N+1行,第一行仅有一个正整数N(不超40),表示东东班里学生的总数,接下来的N行,每行描述一个学生的考试信息,依次为姓名、数学成绩、语文成绩、英语成绩和地理成绩,两两之间用一个空格分隔。注意:姓名(不会有同名现象)都用小写字母表示(至多10个),成绩全部是不超过200的非负整数。

输出

仅包含三行,每行仅包含一个学生的姓名,依次为第一名到第三名学生的姓名。

样例输入
复制样例数据 4
jing 98 90 87 74
ming 96 92 85 97
jun 95 78 56 91
hong 95 100 85 78

样例输出
ming
hong
jing

还是一道排序题,注意用一下结构体

**#include<bits/stdc++.h>
using namespace std;
struct node {
  string name;
  int a;
  int b;
  int c;
  int d;
  int sum;
}a[1000];
bool cmp(node a,node b) {
  return a.sum>b.sum;
}
int main() {
  int n;
  cin>>n;
  for(int i=0;i<n;i++) {
    cin>>a[i].name>>a[i].a>>a[i].b>>a[i].c>>a[i].d;
    a[i].sum+=a[i].a+a[i].b+a[i].c+a[i].d;
  }
  sort(a,a+n,cmp);
  for(int i=0;i<3;i++)
  cout<<a[i].name<<endl;
}

问题 F: 计算比分

题目描述

2016年8月,中国奥运健儿在里约奥运会上捷报频传,特别是中国女排夺冠给国人带来了巨大的惊喜。我们知道最新的排球比赛计分规则是:采用五局三胜制。前四局每局25分,每局比赛达到24分时,双方必须相差2分才能分出胜负;第五局为15分,当达到14分时,双方必须相差2分才能决出胜负;如果某一方先胜出三局(不一定是连续的三局)比赛自动终止。现在给出某次A队和B队进行练习赛的记录,请你按上述规则计算他们比赛的比分。记录方法是:A队一次得分就记录一个A,B队一次得分就记录一个B。
现在给你一次练习赛记录的结果,请你编程计算出此次比赛各局的比分,输出获胜的比赛队伍以及各局的比分。

输入

仅一行,包含一个仅出现大写A和大写B的字符串,表示一场比赛的结果,所给数据保证符合实际,字符个数少于150。

输出

共有若干行,第一行仅一个字符A或B,表示获胜的队伍,接下来的若干行依次为比赛每局的比分,每行描述一局比赛的结果。

样例输入
复制样例数据 AAAAAAAAABAAAAABBAAAAABAAAAAABAAABAABAAAAAABBAAAABAAAAAAAAAABAABAABBBAAAAAAAAAAAAAAAAAAAAA

样例输出
A
25:4
25:6
25:5

这是一道典型的模拟题,做出来以后感觉自己把所有的情况都考虑到了,就是wa,都不知道哪里错了,如果在看这篇博客的兄弟能看出来我这个代码哪里出了问题,能不能告诉我一下,谢谢大佬们!!!

/*#include
using namespace std;
int s1[100];
int s2[100];
int main() {
  string a;
  cin>>a;
  int l=a.size();
  int k;
  int sum1=0;
  int sum2=0;
  int b=0;
  int c=0;
  int js=0;
  for(int i=0;i=2||sum2==25&&sum2-sum1>=2) {
      s1[k]=sum1;
      s2[k]=sum2;
      if(sum1==25)
      b++;
      else if(sum2==25)
      c++;
      sum1=0;
      sum2=0;
      k++;
      js++;
    }
    if(b==3||c==3)
    break;
    if(js==5) {
      if(sum1==14&&sum1-sum2>=2||sum2==14&&sum2-sum1>=2) {
        s1[k]=sum1;
        s2[k]=sum2;
        if(sum1==14)
        b++;
        else if(sum2==14)
        c++;
      }
    }
  }
  if(b>c)
  cout<<'A'<

我终于知道哪里错了!!并且进行了修改!!!原来一直提醒我运行时错误的原因是我的k没赋初值。。。下次可不能这么粗心了! 先上一个改正以后的ac代码 而且b和c的判断必须放最下面,也不能放到判断的里面,不然永远走不出循环了。

2018-2019赛季多校联合新生训练赛第六场补题与题解(中石油)_第3张图片
下面的555来记录我re的痛苦心路历程

#include
using namespace std;
int s1[555];
int s2[555];
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);//这是打开csdn现写的。。。大佬提醒我说我又没关同步。。
  string a;
  cin>>a;
  int l=a.size();
  int k=0;
  int sum1=0;
  int sum2=0;
  int b=0;
  int c=0;
  int cc=0;
  for(int i=0;i<l;i++) {
    if(a[i]=='A')
    sum1++;//计算一下当前A的分数
    else if(a[i]=='B')
    sum2++;//计算B分数
    if(cc<4) {
    if(sum2>=25&&sum2-sum1>=2) {
      s1[k]=sum1;
      s2[k]=sum2;
      c++;
      sum1=0;//更新分数
      sum2=0;
      k++;
      cc++;//增加次数
    }
    else if(sum1>=25&&sum1-sum2>=2) {
      s1[k]=sum1;
      s2[k]=sum2;
      b++;
      sum1=0;
      sum2=0;
      k++;
      cc++;
    }
  }
  else  {
      if(sum1>=15&&sum1-sum2>=2) {
        s1[k]=sum1;
        s2[k]=sum2;
        b++;
        cc++;
        sum1=0;
        sum2=0;
        k++;
      }
      else if(sum2>=15&&sum2-sum1>=2) {
        s1[k]=sum1;
        s2[k]=sum2;
        c++;
        cc++;
        sum1=0;
        sum2=0;
        k++;
    }
  }
  if(b==3||c==3)//跳出循环的条件
  break;
}
  if(b>c)//胜利判定
  cout<<'A'<<endl;
  else
  cout<<'B'<<endl;
  for(int i=0;i<k;i++)
  cout<<s1[i]<<':'<<s2[i]<<endl;//不要忘记endl!!!
}

问题 G: 手机号加密

题目描述

小睿同学常在网上备份通讯录,他担心通讯录中手机号码和对应人的相关信息一旦泄露就会留下后患,所以,他想将手机号加密后再上传备份。小睿对二进制码很有研究,他给出的加密规则是:先将11位的手机号码后八位转换成二进制数,然后将该二进制数高位补零到27位后左右翻转,再将翻转后的二进制数转换成十进制数处理成八位作为加密后手机号码的后八位(若转换后不到八位则高位补零到八位,若多于八位只取低八位)。例如:他的朋友的手机号码是13021246316,应将后八位21246316转换成二进制数A=1010001000011000101101100,25位的A高位补两个0后再翻转得到二进制数B=001101101000110000100010100,再将B转化为十进制数为28598548,所以加密后的手机号码为13028598548。实际上小睿的加密规则还有后续步骤,但为简化解题,本题给出手机号的后八位,你只需编程按上述加密规则处理成符合要求的新号码的后八位即可,其它步骤不用你去完成。

输入

仅有一行,只包含八个数字,无其它字符。

输出

仅有一行,只包含八个数字,无其它字符。

样例输入
复制样例数据 21246316

样例输出
28598548

此处无声胜有声(待解决2333)

问题 H: 学生代表

题目描述

根据上级文件的通知,晨晨学校要挑选一个学生代表,参加区学生代表大会。学校领导想根据学生们平时的表现,找到一个各方面表现都比较平均的学生参加。
刚好,学生根据平时的表现都有自己的德育操行分r (1≤r≤1000),为了尽快找到这名代表,学校领导把学生排成n×n (2≤n≤99, n为奇数)队列,他叫每一行的同学找出自己行的德育操行分在中间位置的同学(所谓中间位置也就是行里面有一半的同学的操行分大于或等于这个学生的操行分数,并且同时有一半的学生的操行分小于或等于这个学生的操行分数)。然后,在每一行中间位置的这些学生中再次找出处于中间位置的那个学生。那么这个学生就是最后参加学生代表大会的学生了。
给出n×n的学生队列,找到其中的学生代表的操行分数。

输入

第一行:一个整数n;
第2…n+1行:每一行有n个整数,分别代表这一行里面每个学生的操行分。

输出

一个整数,学生代表的操行分数。

样例输入
复制样例数据 5
1 5 3 9 5
2 5 3 8 1
6 3 5 9 2
8 8 3 3 2
5 4 4 4 4

样例输出
4

提示

第一行中间位置的为5,第二行为3、第三行为5、第四行为3、第五行为4。
然后在5 3 5 3 4中找到中间位置为4。

这个题可以边输入边sort排序,排序完成以后再把中间那一项存到b数组中,注意i从1开始,这样就可以保证n/2的那一项是是中间那一项,再排序一下输出中间值就行啦~?代码

#include
using namespace std;
int b[200];
int a[200];
int main() {
  int n;
  cin>>n;
  int k=0;
  int l=n;
  while(n--) {
    for(int i=1;i<=l;i++)
    cin>>a[i];
    sort(a+1,a+l+1);
    int c=l/2;
    b[k]=a[c+1];
    k++;
  }
  int d=k/2;
  sort(b,b+k);
  cout<<b[d];
}

问题 I: 拯救花园
题目描述

一天,晨晨发现自己的n(2≤n≤100)只兔子跑到自己的花园里面,它们在尽情的吃着她的宝贝花卉。晨晨看在眼里痛在心里,她现在只能把兔子逐个的抓回笼子里面。而送每只兔子回去的时间都不同,例如送第i只兔子回去需要ti(1≤ti≤100)单位时间,那么晨晨送第i只兔子来回共需要花费2*ti单位时间,另外每一只兔子单位时间的破坏力都不同,例如第i只兔子单位时间内破坏di (1≤di≤100)朵花。
现在的问题是,晨晨如何安排送这n只兔子回笼子才能使这些兔子的破坏最小。

输入

第一行:一个整数n(1≤n≤100);
接着有n行,每行两个空格分开的整数ti di,分别代表第i只兔子的送回去的时间,和单位时间破坏力。

输出

一行:一个整数,代表这些兔子破坏多少花卉。

样例输入
复制样例数据 6
3 1
2 5
2 3
3 2
4 1
1 6

样例输出
86

提示

晨晨送兔子回去的顺序分别为:6, 2, 3, 4, 1, 5。其中先送第6只兔子回去,剩余兔子破坏(1+5+3+2+1)*2=24朵花;送第2只兔子回去,剩余兔子破坏(1+3+2+1)*4=28朵花;以此类推,送第3、4、1只兔子回去剩余兔子的破坏分别为16、12和6朵花;最后送第5只兔子回去的时候,没有兔子在花园里面了,所以破坏0朵花,最后总共破坏24 + 28 + 16 + 12 + 6 = 86朵花。

此处无声胜有声(待解决2333)

问题 J: 摘李子

题目描述

六一儿童节就要到了,晨晨学校组织n位学生去农场摘李子。为了体现同学友好,大家把摘到的李子集中起来,然后平均分配给学生,剩余的李子就送给老师;另外,为了让老师也更多地分享同学们的快乐,同学们还约定:如果按前面办法分配后老师得到的李子数比每个同学的少,则每位同学再拿一个出来送给老师。
现在晨晨想知道每位同学最后能收获多少个李子?送给了老师多少个李子?

输入

第一行:一个整数n(1≤n≤200)。
第二行:n个200以内的正整数,它们之间用一个空格隔开,代表每人摘到的李子数。

输出

第一行:一个整数,代表每位学生最后能收获的李子数。
第二行:一个整数,代表老师最后能收到的李子数。

样例输入
复制样例数据 4
3 5 2 1

样例输出
2
3

这题刚开始wa了一次,是因为给老师分李子的时候太蠢忘了*n了,后来改了一遍就过了?

#include
using namespace std;
int a[1000];
int main() {
  int n;
  cin>>n;
  int sum=0;
  for(int i=0;i<n;i++) {
    cin>>a[i];
    sum+=a[i];
  }
  int ave=0;
  ave=sum/n;
  int ls=0;
  ls=sum-ave*n;
  if(ave>ls) {
    ave--;
    ls+=n;
    cout<<ave<<endl<<ls;
  }
  else
  cout<<ave<<endl<<ls;
}

问题 K: 阅读训练

题目描述

一天晨晨在做阅读训练。她拿了一本包括n篇文章的小说集,第i篇文章包括bi (1≤bi≤100)页,已知晨晨每读一页都要花一分钟。假设晨晨开始阅读小说第一页的时间起点为0,她读第一篇文章从时间点0到时间点b1-1,第二篇文章从时间点b1到时间点b1+b2-1,依此类推…,阅读第n篇文章的时间点b1+b2+…+bn-1到时间点b1+b2+…+bn-1+bn-1。那么,当在时间点t时(0≤t<阅读总时间),你知道晨晨在阅读第几篇文章吗?
其实晨晨的好奇心比你还强,虽然阅读还未正式开始,但她很想知道在未来Q个时间点时,自己分别会在阅读哪一篇文章?
严重偏文科的晨晨,感觉这个问题很棘手,就想请你这个电脑高手帮忙。
例如:如果一本书包括三篇文章:第一篇文章2页,第二篇文章1页,第三篇文章3页,那么时间点与所读文章(序号)的关系如下图所示:

在这里插入图片描述

输入

第一行:包括空格分开的两个整数N和Q (其中1≤n≤100,1≤Q≤1000) 。
接下来的N行,每行一个整数代表每篇文章的页数。
再接下来是Q行,每行一个整数代表一个时间点。

输出

总共Q行,每行一个数,代表按输入顺序的每个时间点正在阅读的文章序号。

样例输入
复制样例数据 3 5
2
1
3
2
3
4
0
1

样例输出
2
3
3
1
1

这题当时读题都读了半天,后来读懂以后for循环里也调了半天才做出来,可以说是非常恶心人了!最后家还得单独判断一下最后算出来的s是否比总篇章数多,因为我在做的时候,输了几个例子进去,发现出的结果居然比总篇章数还多,于是就加了一个判断条件,然后就a了 代码?

#include
using namespace std;
int a[10000];
int main() {
  int n,q;
  cin>>n>>q;
  int x;
  int b[10000];
  int k=0;
  int s=0;
  for(int i=0;i<n;i++)
  cin>>a[i];
  for(int i=0;i<q;i++) {
    cin>>x;
    s=0;
    for(int j=0;j<n;j++) {
      if(x<a[j])
      break;
      if(x>=a[j]) {
        x-=a[j];
        s++;
      }
    }
    if(x>0)
    s++;
    else if(x==0)
    s++;
    if(s<=n)
    b[k]=s;
    else
    b[k]=n;
    k++;
 }
  for(int i=0;i<k;i++)
  cout<<b[i]<<endl;
}

问题 L: 填字游戏

题目描述

六一儿童节就要到了,晨晨的学校进行游园活动,其中一个游戏为填字游戏,规则为:有一个R行C列的棋盘(2≤R,C≤25),棋盘上的每一个格子要么是空的,可以填一个十进制数字;要么是堵上的,以字符“#” 表示(即不能填东西)。棋盘中从左往右连续的数字排列可视为一个十进制整数。
现在给你一个已填好的棋盘,请你帮忙找出棋盘里面最小的整数。

输入

第一行:包括两个数,R和C(2≤R,C≤25),表示R行C列。
接着R行中每行包括C个字符,这些字符要么是数字,要么是“#”。输入数据保证存在解,不存在前导0的情况(例如:01,002)。

输出

棋盘中最小的整数。

样例输入
复制样例数据 3 6
3#5789
897#51
163#31

样例输出
3

提示

对于60%的数据,2≤R,C≤5;
对于80%的数据,2≤R,C≤18;
对于100%的数据,2≤R,C≤25;

此处无声胜有声(待解决2333)

问题 M: 铺地砖

题目描述

一天,晨晨的数学老师布置了一道题目,大意如下:用1×1和2×2的磁砖不重叠地铺满n×3的地板,共有多少种方案?
例如:n=1时:1×3的地板方法就一个,直接由三个1×1的磁砖铺满。
n=2时:2×3的地板可以由下面3种方案铺满:

2018-2019赛季多校联合新生训练赛第六场补题与题解(中石油)_第4张图片

输入

第一行:一个整数n(1≤n≤100)。

输出

输出铺满n×3的地板的方案数。

样例输入
复制样例数据 3

样例输出
5

提示

对于20%的数据,1≤n≤15;
对于50%的数据,1≤n≤30;
对于100%的数据,1≤n≤100;

此处无声胜有声(待解决2333)

你可能感兴趣的:(周赛/中石油题解)