专栏文章

题解

个人记录参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mir1oysp
此快照首次捕获于
2025/12/04 14:18
3 个月前
此快照最后确认于
2025/12/04 14:18
3 个月前
查看原文

T1 小埋的最大差值

额,就是 钱瑞和 前缀和遍历一下就好了
CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;
int t, n, a[1000005], s[1000005];
int check (int k) {
	int x = LLONG_MIN, y = LLONG_MAX;
	for (int i = k; i <= n; i += k) {
		x = max(abs(s[i] - s[i - k]), x);
		y = min(abs(s[i] - s[i - k]), y);
	}
	return x - y;
}
signed main (void) {
	cin >> t;
	int sum = 0;
	while (t--) {
		sum = 0;
		memset(s, 0, sizeof(s));
		cin >> n;
		int l = LLONG_MAX, r = LLONG_MIN;
		for (int i = 1; i <= n; i++) {
			cin >> a[i];
			s[i] = s[i - 1] + a[i];
			l = min(l, a[i]);
			r = max(r, a[i]);
		}
		sum = max(sum, r - l);
		for (int i = 1; i <= 2 * sqrt(n); i++) {
			if (n % i == 0) {
				sum = max(sum, check(i));
				sum = max(sum, check(n / i));
			}
		}
		cout << sum << endl;
	}
	return 0;
}
用define int long long 蔡老师应该不会说我吧

T2 白令海峡

思路:二分加搜索,二分两座大陆会分隔开来的时间,搜索能否从上面走到下面
自己的代码没写出来
把余帅的部分代码粘上来
CPP
void dfs(int xx,int yy){
	vis[xx][yy]=1;
	for(int i=0;i<4;i++){
		int tx=xx+dx[i],ty=yy+dy[i];
		if(tx<0||tx>n-1||ty<0||ty>m-1){
			continue;
		}
		if(mp[tx][ty]=='1'||vis[tx][ty]!=0){
			continue;
		}
		dfs(tx,ty);
	}
}
int check(int s){
	memset(vis,0,sizeof(vis));
	for(int i=1;i<=s;i++){
		vis[x[i]][y[i]]=2;
	}
	for(int i=0;i<m;i++){
		if(mp[0][i]=='0'&&vis[0][i]==0){
			dfs(0,i);
		}
	}
	for(int i=0;i<m;i++){
		if(vis[n-1][i]==1){
			return 1;
		}
	}
	return 0;
}
呜呜呜,写出来了
CPP
#include <bits/stdc++.h>
#define int long long
using namespace std;
int t, n, m, q, sx, sy;
char a[505][505], b[505][505];
bool vis[505][505], flag = false;
int x[250005], y[250005], dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
struct node {
	int x, y;
};
void dfs(int x, int y) {
	if (x == n) {
		flag = true;
		return;
	}
	if (flag) return ;
	for (int i = 0; i < 4; i++) {
		int tx = dx[i] + x, ty = dy[i] + y;
		if (tx < 1 || ty < 1 || tx > n || ty > m || vis[tx][ty] || b[tx][ty] == '1') continue;
		vis[tx][ty] = true;
		dfs(tx, ty);
	}
}
bool check(int mid) {
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			vis[i][j] = false;
		}
	}
	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			b[i][j] = a[i][j];
		}
	}
	for (int i = 1; i <= mid; i++) b[x[i]][y[i]] = '1';
	flag = false;for (int i = 1; i <= m; i++)if (b[1][i] == '0') dfs(1, i);return flag;
}
signed main() {
	cin >> t;
	while (t--) {
		int year,cnt=0,num=0;
		cin >> n >> m;
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= m; j++) {
				cin >> a[i][j];
				vis[i][j] = false;
			}
		}
		cin >> q;
		for (int i = 1; i <= q; i++) cin >> x[i] >> y[i], x[i]++, y[i]++;
		if (check(q)) {
			cout << -1 << endl;
			continue;
		}
		int l = 0, r = q, mid;
		while (l < r) {
			mid = l + r >> 1;
			check(mid) ? l = mid + 1 : r = mid;
		}
		cout << r << endl;
	}
	return 0;
}

T3

可以 bfs 预处理出每个点到点 1、s1、s2 的距离,然后枚举每一个点作为分叉点,如果满足条件就更新答案。
CPP
#include <bits/stdc++.h>
#define maxn 3005
#define inf 0x3f
using namespace std;
inline int read() {
	int x = 0, w = 1;
	char ch = getchar();
	while (ch > '9' || ch < '0') {
		if (ch == '-')w = -1;
		ch = getchar();
	}
	while (ch >= '0' && ch <= '9')x = x * 10 + ch - '0', ch = getchar();
	return x * w;
}

struct node {
	int nxt, to;
} edge[maxn << 1];
int dis[3][maxn], head[maxn];
int s1, s2, t1, t2, tot, n, m;
queue<int> q;

inline void add(int u, int v) {
	edge[++tot].nxt = head[u];
	edge[tot].to = v;
	head[u] = tot;
}

inline void addedge(int u, int v) {
	add(u, v), add(v, u);
}

void bfs(int st, int *dis) {
	q.push(st);
	dis[st] = 0;
	while (!q.empty()) {
		int u = q.front();
		q.pop();
		for (int i = head[u]; i; i = edge[i].nxt) {
			int v = edge[i].to;
			if (dis[v] > dis[u] + 1)
				dis[v] = dis[u] + 1, q.push(v);
		}
	}
}

int main(void) {
	n = read(), m = read();
	for (int i = 1; i <= m; i++) {
		int u = read(), v = read();
		addedge(u, v);
	}
	memset(dis, inf, sizeof(dis));
	s1 = read(), t1 = read(), s2 = read(), t2 = read();
	bfs(1, dis[0]), bfs(s1, dis[1]), bfs(s2, dis[2]);
	int ans = inf;
	for (int i = 1; i <= n; i++)
		if (dis[0][i] + dis[1][i] <= t1 && dis[0][i] + dis[2][i] <= t2)
			ans = min(ans, dis[0][i] + dis[1][i] + dis[2][i]);
	if (ans == inf) puts("-1");
	else printf("%d\n", m - ans);
	return 0;
}

T4

评论

0 条评论,欢迎与作者交流。

正在加载评论...