整体感受
这一次学长拉题终于手下留情了一次,没有到一题做不出来的地步
本周比赛题
大致题意:
有三堆糖果,爱丽丝和鲍勃各自任意挑选一堆,第三堆糖果两个人商量着分配,分配的结果是两个人必须拥有相同数量的糖果(如果有多的糖果将会丢掉),问分配完成后两人最多拥有多少颗糖果。
解题思路:
将三个整数相加,判断是奇数还是偶数,如果是偶数两人正好可以完成分配而不用丢弃糖果,如果是奇数那么提前丢弃一颗糖果,使之变成偶数,再进行分配即可
//代码实现
#include <iostream>
using namespace std;
int main(){
long long n, a, b, c, d;
scanf("%lld", &n);
for(int i=0; i<n; i++){
scanf("%lld%lld%lld", &a, &b, &c);
d = a+b+c;
if(d%2 == 0){
printf("%lld\n", d/2);
}else{
printf("%lld\n", --d/2);
}
}
return 0;
}
大致题意:
小女孩Tanya在一栋有n层楼梯的大楼中爬楼梯,每到新的一层爬楼梯时都会用数字1、2、3、4……记录楼梯数,现在给你这样一串数字,让你判断Tanya一共爬了几层楼,并且按顺序输出每层楼的楼梯数
解题思路:
统计楼层数只需遍历序列中1的个数即可
获取每层楼的楼梯阶数可以从序列中第二个1开始向前读取一位,该数即为上一层楼的阶梯数(注意:最后一层的阶梯数只能额外加进去,因为最后一层之后没有1)
//代码实现
#include <iostream>
#include <vector>
using namespace std;
int main(){
int n, a, b=1, c=0;
vector<int> v;
vector<int> k;
scanf("%d", &n);
for(int i=0; i<n; i++){
scanf("%d", &a);
v.push_back(a);
}
for(int i=0; i<v.size(); i++){
if(v[i]==1 && i!=0){
b++;
k.push_back(v[i-1]);
}
}
printf("%d\n", b);
for(int i=0; i<k.size(); i++){
printf("%d ", k[i]);
}
printf("%d", v[v.size()-1]);
return 0;
}
大致题意:
你收到了一本死亡笔记,你必须连续n天写下一定数量的名字,已知每页纸只能写下m个名字,本页未写完第二天要接着写,直到写完了才可以翻页,现在给你每天需要写的名字数量,问:每天需要翻页几次
解题思路:
声明一个变量存储好当前页数写了多少个名字,每到新的一天将需要写的名字数量加到这个变量上,然后计算这些名字需要写多少页笔记,跳到新的一天前将变量对每页能容纳的名字数取余,循环进行即可得到答案
//代码实现
#include <iostream>
using namespace std;
int main(){
int n, m, a, b=0, c=0;
scanf("%d%d", &n, &m);
for(int i=0; i<n; i++, c=0){
scanf("%d", &a);
b += a;
while(b >= m){
c += b/m;
b = b%m;
}
printf("%d ", c);
}
return 0;
}
大致题意:
一群很闲的人来到一个地方记录很多堆石头,每堆石头的数量任意,这群人可以拿走或移动这些石头,现在有两次统计石头的数据记录,问他们的统计是否出错了
解题思路:
只要第二次的石头数量不变多即可,将第一次、第二次的每一堆石头相加,判断并输出结果
//代码实现
#include <iostream>
using namespace std;
int main() {
int a, b, c, d;
scanf("%d", &a);
for(int i=0; i<a; i++){
scanf("%d", &b);
c += b;
}
for(int i=0; i<a; i++){
scanf("%d", &b);
d += b;
}
if(a<b) printf("No");
else printf("Yes");
}
大致题意:
n个男孩,m个女孩,男孩用B表示,女孩用G表示,让男孩女孩最大程度上交叉排列,答案不唯一,满足即可
解题思路:
如果男孩比女孩多,则输出n个BG然后输出m-n个B,反之同理
//代码实现
#include <bits/stdc++.h>
using namespace std;
int n,m;
int main() {
ifstream fin("input.txt");
ofstream fout("output.txt");
fin >> n >> m;
for (int i = 0; i < n + m; i++) {
fout << "BG"[i<(min(n,m)*2)?(((m>n)+i)%2):(m>n)];
}
}
大致题意:
现有n个数,将这n个数分成m段,判断是否存在一种划分使得这m段每段内部之和为奇数
解题思路:
因为偶数不会影响到是否能出现奇数段,所以本题只需判断这n个数字中是否至少包含m个奇数,如果满足这个条件,则可以出现m段段内和为奇数的情况。综上,判断n个数中是否有n个奇数。
//代码实现
#include <iostream>
using namespace std;
int main() {
int q;
cin >> q;
for (int i = 0; i < q; ++i) {
int n, k;
cin >> n >> k;
vector<int> a(n);
int cntodd = 0;
for (int j = 0; j < n; ++j) {
cin >> a[j];
cntodd += a[j] % 2;
}
if (cntodd < k || cntodd % 2 != k % 2) {
cout << "NO" << endl;
continue;
}
cout << "YES" << endl;
for (int j = 0; j < n; ++j) {
if (k == 1) break;
if (a[j] % 2 == 1) {
cout << j + 1 << " ";
--k;
}
}
cout << n << endl;
}
return 0;
}