【解题报告】【比赛复现】洛谷入门赛 #17 题解

洛谷入门赛 #17 题解

今日推歌:《春嵐 feat.初音ミク》 john

感觉这首都快成周榜战神了(

Before

关于我做入门赛的精神状态:

image

没做T4,因为题面读得我头疼……而且大模拟不想做(虽然也不是多大的模拟

展开目录


A 食堂

先读题:

image

注意以上↑几点

可以考虑一个式子解决,最小化代码行数。首先每个学生每天只吃一餐,每餐只吃一份米、菜、肉,所以可得 \(b\) 个学生每天消耗米、菜、肉的量分别为 \(bR\),\(bV\)\(bM\).

每个老师每天吃两餐,每餐消耗两份米、三份菜和肉,所以可得 \(a\) 个学生每天消耗米、菜、肉的量分别为 \(4aR\),\(6bV\),\(6bM\).

最后把米、菜和肉的消耗量分别相加并输出即可。

展开代码
#include <bits/stdc++.h>
#define ll long long
#define MyWife Cristallo
using namespace std;
const int N = 1e5 + 5;
int a, b, r, v, m;
int main() {
	scanf("%d%d%d%d%d", &a, &b, &r, &v, &m);
	printf("%d %d %d\n", (b + 4 * a) * r, (b + 6 * a) * v, (b + 6 * a) * m);
	return 0;
}

B 数学选择题

首先把简单题加的分、困难题加的分和困难题扣的分算出来(其中 \(\text{困难题扣的分}=\text{困难题总分} - \text{困难题加的分}\).)

依照题意判断即可。

顺带一提,因为会涉及到比较多次“如果大于 \(0\) 就输出,小于 \(0\) 就输出 \(0\)”的判断,可以写一个函数。

展开代码
#include <bits/stdc++.h>
#define ll long long
#define MyWife Cristallo
using namespace std;
const int N = 1e5 + 5;
int a, b, c, d, m, jd, kn, jf; 
int ze(int x) {
	if(x > 0) return x;
	return 0;
}
int main() {
	scanf("%d%d%d%d%d", &a, &b, &c, &d, &m);
	jd = 5 * c;
	kn = 20 * d;
	jf = 20 * b - kn;
	if(jd <= m) printf("%d\n", ze(jd - jf));
	else printf("%d\n", ze(jd + kn - jf));
	return 0;
} 

After

image


C 风球

去吧比比鸟,使用烈暴风!(啊?

记录每个等级的风出现的次数,最后进行判断即可。

顺带一提,最好从最大的等级开始判断。

展开代码
#include <bits/stdc++.h>
#define ll long long
#define MyWife Cristallo
using namespace std;
const int N = 1e5 + 5;
int a[9], x, y, z;
int main() {
	for(int i = 1; i <= 8; ++i) {
		scanf("%d", a + i);
		if(a[i] >= 41) ++x;
		if(a[i] >= 63) ++y;
		if(a[i] >= 118) ++z;
	}
	if(z >= 1) puts("10");
	else if(y >= 4) puts("8");
	else if(x >= 4) puts("3");
	else puts("1");
	return 0;
}

E 式神考核

满分的题的总分可以直接得出来,那么剩下的部分中,使得一半分的题最大化,最后多出来的分就是附加题的分。

这个题应该向上取整,因为分数是向下取整的,就说明实际分数高于总分。

展开代码
#include <bits/stdc++.h>
#define ll long long
#define MyWife Cristallo
using namespace std;
const int N = 1e7;
double n, s, m, ttt, i, np;
int main() {
	scanf("%lf%lf%lf", &n, &s, &m);
	double t = N / n, qd = t * (n - m);
	for(i = 1; i <= m; ++i) if(qd + 0.5 * t * i > s) break;
	ttt = qd + 0.5 * t * (--i);
	if(ttt < s) np = s - ttt;
//	cout << m << " " << i << endl;
	printf("p%d(+%d) f%d l%d\n", (int)(n - m), (int)ceil(np), (int)i, (int)(m - i));
	return 0;
}

After

我如此钟爱这道题的因是,这道题浓厚的数学含量让我想起了我一样的数学老师,她发了我,让我意识到我连只物都不如。

image

image

文心一言是什么梗呢?我们都知道文心一言,那么文心一言是什么梗呢?就让小编带大家了解一下,文心一言是什么梗。文心一言是指,洛谷入门赛 #19 赛后,THOI 高一机房试图使用文心一言解决部分问题,但文心一言全部使用 DP 给出了错误解法。以上就是文心一言是什么梗的全部内容了,让我们一起期待文心一言是什么梗的新内容吧

image

image

image

image

我咋每次都卡 E 题(


F 表格处理

可以用三个二维数组来处理,减少思考难度(啊?

我们看这样两个数组: 【跳过】

\(A\) 数组:

\((1, 1)\) \((2, 1)\) \((3, 1)\) \(...\) \((j - 1, 1)\) \((j, 1)\) \((j + 1, 1)\) \(...\) \((m - 1, 1)\) \((m, 1)\)
\((1, 2)\) \((2, 2)\) \((3, 2)\) \(...\) \((j - 1, 2)\) \((j, 2)\) \((j + 1, 2)\) \(...\) \((m - 1, 2)\) \((m, 2)\)
\((1, 3)\) \((2, 3)\) \((3, 3)\) \(...\) \((j - 1, 3)\) \((j, 3)\) \((j + 1, 3)\) \(...\) \((m - 1, 3)\) \((m, 3)\)
\(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\)
\((1, i - 1)\) \((2, i - 1)\) \((3, i - 1)\) \(...\) \((j - 1, i - 1)\) \((j, i - 1)\) \((j + 1, i - 1)\) \(...\) \((m - 1, i - 1)\) \((m, i - 1)\)
\((1, i)\) \((2, i)\) \((3, i)\) \(...\) \((j - 1, i)\) \((j, i)\) \((j + 1, i)\) \(...\) \((m - 1, i)\) \((m, i)\)
\((1, i + 1)\) \((2, i + 1)\) \((3, i + 1)\) \(...\) \((j - 1, i + 1)\) \((j, i + 1)\) \((j + 1, i + 1)\) \(...\) \((m - 1, i + 1)\) \((m, i + 1)\)
\(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\)
\((1, n - 1)\) \((2, n - 1)\) \((3, n - 1)\) \(...\) \((j - 1, n - 1)\) \((j, n - 1)\) \((j + 1, n - 1)\) \(...\) \((m - 1, n - 1)\) \((m, n - 1)\)
\((1, n)\) \((2, n)\) \((3, n)\) \(...\) \((j - 1, n)\) \((j, n)\) \((j + 1, n)\) \(...\) \((m - 1, n)\) \((m, n)\)

\(B\) 数组:

\((1, 1)\) \((2, 1)\) \((3, 1)\) \(...\) \((2j - 1, 1)\) \((2j, 1)\) \((2j + 1, 1)\) \(...\) \((2m - 1, 1)\) \((2m, 1)\)
\((1, 2)\) \((2, 2)\) \((3, 2)\) \(...\) \((2j - 1, 2)\) \((2j, 2)\) \((2j + 1, 2)\) \(...\) \((2m - 1, 2)\) \((2m, 2)\)
\((1, 3)\) \((2, 3)\) \((3, 3)\) \(...\) \((2j - 1, 3)\) \((2j, 3)\) \((2j + 1, 3)\) \(...\) \((2m - 1, 3)\) \((2m, 3)\)
\(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\)
\((1, 2i - 1)\) \((2, 2i - 1)\) \((3, 2i - 1)\) \(...\) \((2j - 1, 2i - 1)\) \((2j, 2i - 1)\) \((2j + 1, 2i - 1)\) \(...\) \((2m - 1, 2i - 1)\) \((2m, 2i - 1)\)
\((1, 2i)\) \((2, 2i)\) \((3, 2i)\) \(...\) \((2j - 1, 2i)\) \((2j, 2i)\) \((2j + 1, 2i)\) \(...\) \((2m - 1, 2i)\) \((2m, 2i)\)
\((1, 2i + 1)\) \((2, 2i + 1)\) \((3, 2i + 1)\) \(...\) \((2j - 1, 2i + 1)\) \((2j, 2i + 1)\) \((2j + 1, 2i + 1)\) \(...\) \((2m - 1, 2i + 1)\) \((2m, 2i + 1)\)
\(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\) \(...\)
\((1, 2n - 1)\) \((2, 2n - 1)\) \((3, 2n - 1)\) \(...\) \((2j - 1, 2n - 1)\) \((2j, 2n - 1)\) \((2j + 1, 2n - 1)\) \(...\) \((2m - 1, 2n - 1)\) \((2m, 2n - 1)\)
\((1, 2n)\) \((2, 2n)\) \((3, 2n)\) \(...\) \((2j - 1, 2n)\) \((2j, 2n)\) \((2j + 1, 2n)\) \(...\) \((2m - 1, 2n)\) \((2m, 2n)\)

可以发现,\(A\) 数组是 \(B\) 数组按照题意压缩后的数组。

因此我们可以坐标的对应关系把给定数组进行压缩。

至于翻转:

image

展开代码
#include <bits/stdc++.h>
#define ll long long
#define MyWife Cristallo
using namespace std;
const int N = 1e5 + 5;
int n, m, a[2005][2005], b[2005][2005], c[2005][2005];
int main() {
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= 2 * n; ++i) for(int j = 1; j <= 2 * m; ++j) scanf("%d", a[i] + j);
	for(int i = 1; i <= n; ++i) for(int j = 1; j <= m; ++j) b[i][j] = a[2 * i - 1][2 * j] + a[2 * i][2 * j] + a[2 * i][2 * j - 1] + a[2 * i - 1][2 * j - 1];
	for(int i = 1; i <= m; ++i) for(int j = 1; j <= n; ++j) c[i][j] = b[j][i];
	for(int i = 1; i <= m; ++i) {
		for(int j = 1; j <= n; ++j) printf("%d ", c[i][j]);
		putchar('\n');
	}
	return 0;
}

After

image


G 基因

后面这几道里最简单的。

从头到尾扫一遍,看能不能和对面的配对。

一种省时做法:扫一半,遇到配对的答案 \(+2\).

展开代码
#include <bits/stdc++.h>
#define ll long long
#define MyWife Cristallo
using namespace std;
const int N = 1e5 + 5;
int T, n;
ll ans;
string s;
bool charity(char c) {return (c == 'A' || c == 'T' || c == 'C' || c == 'G'); }
char cirtus(char c) {
	if(c == 'A') return 'T';
	if(c == 'T') return 'A';
	if(c == 'C') return 'G';
	if(c == 'G') return 'C';
}
int main() {
	scanf("%d", &T);
	while(T--) {
		cin >> n >> s;
		s = " " + s;
		for(int i = 1; i <= n; ++i) {
//			cout << s[i] << " " << n - i + 1;
			if(!charity(s[i])) {ans = 0; break; }
			if(s[i] == cirtus(s[n - i + 1])) ans += i;
		}
		printf("%lld\n", ans);
		ans = 0;
	}
	return 0;
}

After

image


方程求解

第一遍没好好看,以为是二元的,再看一眼就会了。

科普一个常识:输入 \(+5\) 和输入 \(5\) 的效果是一样的。

所以可以直接带着符号输入进来,用 \(scanf\) 过滤 \(x\)\(=\).统计每个解都是什么,可以离线预处理解个数的前缀和(仮)或在线循环查找(效率稍微慢点)

一元一次方程的解法:

\[若有方程\ ax + b = c \]

\[则有\ x = \dfrac{c - b}{a} \]

另外一个区间内所有相同的解都算作一个解。

展开代码
#include <bits/stdc++.h>
#define ll long long
#define MyWife Cristallo
using namespace std;
const int N = 1e5 + 5;
int n, q, x, y, z, l, r, ans[2005], a[2005];
int main() {
	scanf("%d%d", &n, &q);
	for(int i = 1; i <= n; ++i) {
		scanf("%dx%d=%d", &x, &y, &z);
		a[(z - y) / x] = 1;
	}
	for(int i = 1; i <= 2000; ++i) ans[i] = ans[i - 1] + a[i];
	for(int i = 1; i <= q; ++i) {
		scanf("%d%d", &l, &r);
		printf("%d\n", ans[r] - ans[l - 1]);
	}
	return 0;
}

结语

image

早该改这个缺省源了

posted @ 2024-02-20 15:15  _Kiichi  阅读(33)  评论(3编辑  收藏  举报