2019寒假集训第一场(新生场)中石油补题和题解

这次比赛不知道为啥中石油那边没有公开,只有中石油和徐州工程的能做,所以只有之后的补题,就在下面,感觉英文题很友好啊能看懂,希望都是这样的题23333

问题 A: 数方格

题目描述

余姚市要新建一个广场,为了美观,要求完全是正方形。目前正在规划当中,正方形的大小和位置都在热烈的讨论之中。假设将可用于造广场的区域看成一个矩形,由11的单位正方形构成。如下图:这是一个46的矩形区域。

在这里插入图片描述

广场要求必须在这个矩形范围内,广场边线不能跨过任意一个单位正方形内部,只能与正方形边线重合,且广场必须为正方形。那么上图中,以下4种正方形均为可行方案:

在这里插入图片描述

市民们提出了很多建造广场的方案。现在领导想要知道,到底有多少种不同的方案可以选择?请你设计一个程序,来计算以下建造广场的最多可行方案数。

输入

第一行两个整数n和m(1<=n,m<=1000),表示用于建造广场区域的长和宽。

输出

一个整数,建造广场的可行方案数。

样例输入
复制样例数据 1 5

样例输出
5

这道题的意思是说在给定的n和m范围内,能放多少个ii的正方形,思路是刚开始先加上11的小方块,这是每种情况都会有的,后面再从2*2的方块开始,如果m或者n小于i的话就说明无法放进去正方格了,这时候退出循环,如果能组成,ans就加上m和n里面最大的和最小的分别减去i再加上1 加一的原因是刚开始放进去这也算一种情况,减去i的原因是算一下当前的长宽减去此时长方形后还能组成几种情况最后加完输出就完了 代码?

#include<bits/stdc++.h>
using namespace std;
int main() {
  int n,m;
  cin>>n>>m;
  int ans=0;
  ans+=m*n;
  int h=0;
  int l=0;
  for(int i=2;;i++) {
    if(m<i||n<i)
    break;
    if(m>=i&&n>=i) {
      l=min(m,n)-i+1;
      h=max(m,n)-i+1;
    }
    ans+=l*h;
  }
  cout<<ans;
}

问题 B: 找朋友

题目描述

小学毕业后,同学们都进入了不同的初中,小明非常想念小伙伴们,所以他打算联系小学的同学们。
现在他得到了市内某所初中的所有名单,找出其中小明的小伙伴们。

输入

第一行一个整数n,表示某初中人数。
接下来n行,每行一个字符串,只有小写字母组成,表示该校每个人的拼音。数据保证没有人拼音相同,且已经按照字典序从小到大排序。
第n+2行有一个整数m,表示小明的小伙伴个数。
最后m行,每行一个字符串,只有小写字母组成,表示每个小伙伴的拼音,同样保证没有重复。

输出

输出所有在该校的小伙伴的拼音。
每行一个拼音,顺序按照小伙伴给出的顺序。

样例输入
复制样例数据 3
alice
bob
zhangsan
2
lisi
zhangsan

样例输出
zhangsan

提示

对于100%的数据,n<=100000,m<=10000,每个人拼音长度不超过15。
所有数据,学校学生名单中的姓名,都是按照字典序从小到大排序。

很显然的一道map水题,定义一个String-int类型的map 输入名字的同时给map对应的map赋值,最后由于是先输入在输出,把要输入的名字存到string数组中,如果出现过就让他输出。 代码?:

#include<bits/stdc++.h>
using namespace std;
map<string,int >mp;
int main() {
  int n,m;
  cin>>n;
  string a;
  for(int i=0;i<n;i++) {
    cin>>a;
    mp[a]=1;
  }
  cin>>m;
  string b[10010];
  for(int i=0;i<m;i++) {
    cin>>b[i];
  }
  for(int i=0;i<m;i++) {
    if(mp[b[i]])
    cout<<b[i]<<endl;
  }
}

问题 C: 高校录取

题目描述

高三全省联合模拟考试刚刚结束,经过各科老师的努力,各个学科的改卷工作终于结束了,每位同学的各科分数也已经结算完毕。此时,老师们开始模拟各个高校录取情况。
每个大学有自己的录取范围。例如,清华、北大招生约为理科全省前100名,复旦、上海交大在全省理科101至300名。老师们想要知道哪些同学可以进入某个名校。
可是,统计软件突然失灵,查询和比对工作也无法进行,只有事先已经得到的理科每位同学的各科成绩。现在请你帮助老师编写一个程序,显示出可以进入某高校的名单。
此次考试理科排名规则:
1.按照语文、数学、外语、理科综合四门科目总分由高到低排名;
2.若总分相同,则按照数学成绩由高到低排名;
3.若总分和数学成绩都相同,按照理科综合成绩由高到低排名;
4.若总分、数学、理科综合都相同,按照语文成绩由高到低排名;
5.若总分、数学、理科综合、语文成绩都相同,则按照报名序号从小到大排序(这里报名序号为输入顺序,第1个输入就是1号,第100个输入就是100号)。

输入

第一行三个整数n,a和b,分别表示参加考试的人数和某高校的录取名次范围(从名次a到名次b)。
接下来n行,每行4个整数,表示每位同学的每门学科的成绩。依次为语文、数学、英语、综合。成绩0<=x<=300。

输出

输出b-a+1行,排名在a~b名的同学信息。
每行两个整数,分别为报名序号和总分(报名序号看题目描述),中间用空格分开。

样例输入
复制样例数据 6 3 5
118 139 130 286
105 130 129 296
113 138 123 291
104 133 119 283
89 139 116 287
103 127 118 288

样例输出
2 660
4 639
6 636

提示

对于100%的数据,1<=a<=b<=n<=100000。

排序水题,没有啥好说的,不过注意这里数据很大,我试了一下,用endl的话会tle 最好使用"\n" 这样虽然在循环输入输出的时候显示不出,但是快啊! 从endl到’\n’时间从1980ms减少到了91ms,关闭同步以后变成了42ms所以以后尽量关闭同步和"\n"两步走 代码:?

#include<bits/stdc++.h>
using namespace std;
struct node {
  int yw;
  int sx;
  int yy;
  int lz;
  int zf;
  int id;
}a[100010];
bool cmp (node a,node b) {
  if(a.zf!=b.zf)
    return a.zf>b.zf;
  else {
    if(a.sx!=b.sx)
      return a.sx>b.sx;
    else {
      if(a.lz!=b.lz)
        return a.lz>b.lz;
      else {
        if(a.yw!=b.yw)
          return a.yw>b.yw;
        else {
          return a.id<b.id;
        }
      }
    }
  }
}
int main() {
  int n,b,c;
  cin>>n>>b>>c;
  for(int i=0;i<n;i++) {
    cin>>a[i].yw>>a[i].sx>>a[i].yy>>a[i].lz;
    a[i].id=i+1;
    a[i].zf=a[i].yw+a[i].sx+a[i].yy+a[i].lz;
  }
  sort(a,a+n,cmp);
  for(int i=b-1;i<=c-1;i++) {
    cout<<a[i].id<<" "<<a[i].zf<<"\n";
  }
}

问题 D: 围栏翻新

题目描述

小明的破旧围栏又要喷涂油漆了。围栏由N个木板构成,每个宽度都为1cm,但是高度各不相同。他给自己买了一个喷漆机器,喷涂头恰好也是1cm宽。
小明的喷漆机器是直接喷射的,因此喷头的每一个部位必须一直接触到木板,否则尤其会污染他的农田。并且机器也必须时刻与地面平行。可以看出,小明每次必须在同一高度对木板喷涂,可以从左到右直到没有围栏可以喷漆。这样,若干次喷漆之后,就可以将围栏翻新啦!
由于机器的特殊性,小明希望喷涂的次数尽量的少。如下图的围栏情况,共有5块木板,高度分别为2,3,4,1,2。第一次可以刷15,第二次刷13,第三次刷23,第四次刷33,第五次刷5~5。5次就可以刷完!(刷的顺序可以随意调整,也可以从上面开始刷)

小明想要知道至少需要刷多少次就可以把围栏都刷完,请你帮忙计算一下!

输入

第一行一个整数N,表示木板数量。
接下来N行,每行一个整数,表示每块木板依次的高度。

输出

翻新围栏所需的最少喷漆次数。

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

样例输出
5

提示

100%的数据1<=n<=100000,对于每个木板的高度0<=hi<=10000。

这题是看了mhr大佬的博客才明白的,这里放一下大佬博客:大佬的博客

这题可以分成两步:
1️⃣ 先加上第一列的
2️⃣ 如果后面有大于前面的就加上之间的差,代表需要多涂的次数

这里有几种情况
在这里插入图片描述
代码:

#include<bits/stdc++.h>
using namespace std;
int a[100010];
int main() {
  int n;
  cin>>n;
  for(int i=0;i<n;i++)
  cin>>a[i];
  int sum=0;
  for(int i=0;i<n;i++) {
    if(i==0)
    sum+=a[i];
    else if(a[i]>a[i-1]) {
      sum+=a[i]-a[i-1];
    }
  }
  cout<<sum; 
}

问题 E: Maximum Increase

题目描述

You are given array consisting of n integers. Your task is to find the maximum length of an increasing subarray of the given array.

A subarray is the sequence of consecutive elements of the array. Subarray is called increasing if each element of this subarray strictly greater than previous.

输入

The first line contains single positive integer n (1 ≤ n ≤ 105) — the number of integers.

The second line contains n positive integers a1, a2, …, an (1 ≤ ai ≤ 109).

输出

Print the maximum length of an increasing subarray of the given array.

样例输入
复制样例数据 5
1 7 2 11 15

样例输出
3

这题就是找一下上升序列最长的一个 我写了一个有bug 也不知道为什么 后来又写了一个ac了 代码:

代码(有bug)

#include<bits/stdc++.h>
using namespace std;
int a[100010];
int main() {
  //freopen("abc.txt","r",stdin);
  int n;
  cin>>n;
  int ans=0;
  int maxn=1;
  for(int i=0;i<n;i++) {
    cin>>a[i];
  }
  for(int i=1;i<n;i++) {
    if(a[i]>a[i-1])
    maxn++,ans=max(ans,maxn);
    else
      maxn=1;
    ans=max(ans,maxn);
  }
  cout<<ans;
}

代码(ac)

#include<bits/stdc++.h>
using namespace std;
int a[100010];
int main() {
  //freopen("abc.txt","r",stdin);
  int n;
  cin>>n;
  int ans=0;
  int maxn=1;
  for(int i=0;i<n;i++) {
    cin>>a[i];
  }
  for(int i=1;i<n;i++) {
    if(a[i]>a[i-1])
    maxn++;
    else
      maxn=1;
    ans=max(ans,maxn);
  }
  cout<<ans;
}

5354: Lovely Palindromes

题目描述

Pari has a friend who loves palindrome numbers. A palindrome number is a number that reads the same forward or backward. For example 12321, 100001 and 1 are palindrome numbers, while 112 and 1021 are not.

Pari is trying to love them too, but only very special and gifted people can understand the beauty behind palindrome numbers. Pari loves integers with even length (i.e. the numbers with even number of digits), so she tries to see a lot of big palindrome numbers with even length (like a 2-digit 11 or 6-digit 122221), so maybe she could see something in them.

Now Pari asks you to write a program that gets a huge integer n from the input and tells what is the n-th even-length positive palindrome number?

输入

The only line of the input contains a single integer n (1 ≤ n ≤ 10100 000).

输出

Print the n-th even-length palindrome number.

样例输入
复制样例数据 1

样例输出
11

提示

The first 10 even-length palindrome numbers are 11, 22, 33, … , 88, 99 and 1001.

这题看起来挺厉害的 实际上就是镜像再输出一次副本就行了(原因是第几个这样的数字就是第几种情况) 代码:

#include<bits/stdc++.h>
using namespace std;
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  string aa;
  cin>>aa;
  cout<<aa;
  int l=aa.size();
  for(int i=l-1;i>=0;i--)
  cout<<aa[i];
}

5355: The Same Calendar

题目描述

The girl Taylor has a beautiful calendar for the year y. In the calendar all days are given with their days of week: Monday, Tuesday, Wednesday, Thursday, Friday, Saturday and Sunday.

The calendar is so beautiful that she wants to know what is the next year after y when the calendar will be exactly the same. Help Taylor to find that year.

Note that leap years has 366 days. The year is leap if it is divisible by 400 or it is divisible by 4, but not by 100 (https://en.wikipedia.org/wiki/Leap_year).

输入

The only line contains integer y (1000 ≤ y < 100’000) — the year of the calendar.

输出

Print the only integer y’ — the next year after y when the calendar will be the same. Note that you should find the first year after y with the same calendar.

样例输入
复制样例数据 2016

样例输出
2044

上来我看了一下题读错了题目。。我想成了闰年,想不明白为什么2016下一个不是2020 后来看了日历发现是找两个完全相同的年份,陷入了深思,于是看了mhr大佬的博客后自己模拟了一下,2001年的时候t=1,2002=2…2004之后 t=5 2006年以后t=7 正好在2007年t%7==0了 于是我再去看了一下日历,发现2001年和2007年的日历一模一样 所以要满足两点要求

一、闰年对应闰年,平年对应平年
二、t%7==0的时候满足条件

需要注意的一点是闰年的2月有29天,比别的都多一天,所以到闰年每一年的第一天星期数都会往后推两天,别的都是推一天,所以闰年的时候加2 代码:

#include<bits/stdc++.h>
using namespace std;
bool is_leap(int n) {
  if(n%400==0||n%4==0&&n%100!=0)
  return 1;
  else
  return 0;
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin>>n;
  int day;
  if(is_leap(n)) {
    day=2;
    for(int i=n+1;;i++) {
      if(is_leap(i)&&day%7==0) {
        cout<<i;
        return 0;
      }
      if(is_leap(i))
      day+=2;
      else
      day+=1;
    }
  }
  else {
    day=1;
    for(int i=n+1;;i++) {
      if(!is_leap(i)&&day%7==0) {
        cout<<i;
        return 0;
      }
      if(is_leap(i))
      day+=2;
      else
      day+=1;
    }
  }
}

  • 5
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值