比赛链接:

https://ac.nowcoder.com/acm/contest/11221

A.深渊水妖

思路:

找到每一个非递减的区间,然后将最大的找出来,输出就行,简单水题,比赛的时候连题目都理解错了。

代码:

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define pb push_back
#define PII pair <int, int>
#define se second
const int N = 3e6 + 10;
int n, a[N], T;
void solve(){
	cin >> n;
	for (int i = 1; i <= n; i++)
		scanf("%d", &a[i]);
	int i = 1, j = 1, ans = 0;
	vector <PII> v;
	while (j <= n){
		while (j < n && a[j] <= a[j + 1])
			j++;
		if (a[j] - a[i] >= ans){
			if (a[j] - a[i] > ans){
				ans = a[j] - a[i];
				v.clear();
			}
			v.pb({i, j});
		}
		i = ++j;
	}
	for (auto x : v)
		cout << x.fi << " " << x.se << " ";
	cout << "\n";
}
int main(){
	cin >> T;
	while (T--)
		solve();
	return 0;
}

B.顽皮恶魔

思路:

直接遍历所有植物,判断周围有没有保护伞,要注意一下边界,可以初始化一下。

代码:

#include <bits/stdc++.h>
using namespace std;
#define fi first
#define pb push_back
#define PII pair <int, int>
#define se second
const int N = 1e3 + 10;
int n, m, T, dx[9] = {-1, -1, -1, 0, 0, 0, 1, 1, 1}, dy[9] = {-1, 0, 1, -1, 0, 1, -1, 0, 1};
char a[N][N];
void init(int n, int m){
	for (int i = 1; i <= n + 1; i++)
		for (int j = 1; j <= m + 1; j++)
			a[i][j] = '.';
}
void solve(){
	cin >> n >> m;
	init(n, m);
	int ans = 0;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			cin >> a[i][j];
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
			if (a[i][j] == 'P'){
				int f = 1;
				for (int k = 0; k < 9; k++){
					int x = i + dx[k], y = j + dy[k];
					if (a[x][y] == '*'){
						f = 0;
						break;
					}
				}
				if (f) ans++;
			}
	cout << ans << "\n";
}
int main(){
	cin >> T;
	while (T--)
		solve();
	return 0;
}

C.绝命沙虫

思路:

就按照题目说的操作就行了,主要是卡了精度,解决的办法有两个,可以分别输入 \(m\) 的整数部分和小数部分然后求和,也可以用接近 1 的数替换掉 1 防止卡精度。

代码:

分别读入

#include <bits/stdc++.h>
using namespace std;
int n, T, m, k;
void solve(){
	scanf("%d%d.%d", &n, &m, &k);
	int ans = 0, r, g;
	while (n > 0){
		r = n * 100, g = min(10000, n * 10 * ((m - 1) * 10 + k));
		ans += r / 10 + g / 10;
		n /= 2;
	}
	cout << ans << "\n";
}
int main(){
	cin >> T;
	while (T--)
		solve();
	return 0;
}

替换

#include <bits/stdc++.h>
using namespace std;
int n, T;
double m;
void solve(){
	cin >> n >> m;
	int ans = 0, r, g;
	while (n > 0){
		r = n * 100, g = min(10000.0, n * 100 * (m - 0.99999));
		ans += r / 10 + g / 10;
		n /= 2;
	}
	cout << ans << "\n";
}
int main(){
	cin >> T;
	while (T--)
		solve();
	return 0;
}

D.丛林木马

思路:

容易发现答案就是 \(a * b.size() + b * a.size()\)(a.size() 就是 a 的长度),需要高精,直接上 \(python\)

代码:

t = int(input())
for i in range(t):
    a, b = input().split()
    print((int(a) * len(b) + int(b) * len(a)) % 998244353)

E.变异蛮牛

思路:

长度只有可能是 0 或者 1。
设树中黑点的数量为 cnt,那么容易想到答案就是 \(C_{cnt}^2\) + cnt ,因为任意两个黑点作为边的话,其长度必定为 1,而链中只有一个黑点的时候,其长度也为 1。
黑点的数量我们可以通过树的搜索(bfs,dfs等)去求。

代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
const int N = 3e6 + 10;
LL T, n, u, v, cnt, val[N];
vector <int> e[N];
void dfs(int f, int p){
	if (p == 1) cnt++;
	for (auto x : e[f]){
		if (val[x]) continue;
		val[x] = 1;
		dfs(x, 1 - p);
	}
}
void solve(){
	cin >> n;
	cnt = 0;
	for (int i = 1; i <= n; i++)
		e[i].clear(), val[i] = 0;
	for (int i = 1; i < n; i++){
		scanf("%lld%lld", &u, &v);
		e[u].pb(v);
		e[v].pb(u);
	}
	val[1] = 1;
	dfs(1, 1);
	cout << (cnt * (cnt - 1)) / 2 + cnt << "\n";
}
int main(){
	cin >> T;
	while (T--)
		solve();
	return 0;
}

F.幽暗统领

思路:

\(s\)\(\sum_{i = 1}^n a_i\),mn 为 \(max (\sum_{i = 1}^n a_i)\),res 为 \(s - mn\)
首先要了解树的重心的定义,我们可以知道,当 \(mn * 2 <= s\) 的时候,所有点都可以作为重心。
如果我们设某个链的第 \(i\) 个节点为重心,这条链中左边的节点有 \(a\) 个,右边的节点有 \(b\) 个。我们可以通过把其它链挂在该节点上的操作,使重心落在第 \(i\) 个节点上。
\(mn * 2 > s\) 时,重心一定落在最长的那条链上的某个区间内,接下来就是求这个区间。
根据现有的条件我们可以知道 \(a + b + 1 = mn\),要让重心落在最左边的 \(i\) 上,我们要让左右两边的节点数量尽可能接近,让 \(res + a = b\),那么我们就可以得到 \(a = (mn - res - 1) / 2\) 的关系,即最左边的点就是 \((mn - res - 1) / 2\),右边的节点是和左边的对称的,区间长度就求出来了。

代码:

#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int N = 3e6 + 10;
LL T, n, a[N];
void solve(){
	scanf("%lld", &n);
	LL s = 0, mn = 0;
	for (int i = 1; i <= n; i++){
		scanf("%lld", &a[i]);
		s += a[i];
		mn = max(mn, a[i]);
	}
	if (mn * 2 <= s) cout << s << "\n";
	else{
		LL res = s - mn, a = (mn - res + 1) / 2, b = mn - a + 1;
		cout << b - a + 1 << "\n";
	}
}
int main(){
	cin >> T;
	while (T--)
		solve();
	return 0;
}
posted on 2022-02-26 00:22  Hamine  阅读(62)  评论(0编辑  收藏  举报