2025团体程序设计天梯赛总结
这次天梯赛只拿了197分,本来还想着冲国2的,结果只有国3。
开赛卡了好久,一直看不到题,等到正常了看到只剩2个小时左右了l1还没写完有点慌(后来延时了1小时)
主要有几道l1的题没能第一发ac导致有点浪费时间,不过差1,2个点我就跳了,后来延时1h感觉时间还挺充足的,最后剩1h准备开l3题。
到这个时候问题来了 第一眼看l3-1是个图论感觉没那么好做,就去看l3-2,一开始思路想错了想的递推或者找公式,5分钟暂时没想好,发现l1-6之前跳了,就想着先把l1-6做了,想着数组操作直接用python方便,结果3个操作巨麻烦,写了40min过了样例交上去一个点没过,这下真的心态爆炸了,剩20min想着赶紧做l3,仔细一看l3-1发现是弗洛伊德算法紧急秒了一个,最后没时间调错了一个9分点,只能197遗憾离场。
不过今年确实比去年进步很多,感觉自己还是手速慢了点,以及对有些数组下标处理想的不清楚,后来补题发现l3-2就是个非常简单的前缀和,以后比赛还是不应该乱换题,感觉不难的题就应该多想想,以及l1-6其实用c++stl里内置的函数其实很简单但是因为自己对stl许多函数不熟悉只能手写导致变复杂了。
以下是部分补题
l1-6
用python写了个数组处理发现后两个点会超时,懒得再改c++就直接让ai改成c++了,本题就是暴力模拟3种操作,c++不会超时
点击查看代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
int N, M;
cin >> N >> M;
// 存储输入的初始序列
vector<int> sequence(N);
for (int i = 0; i < N; i++) {
cin >> sequence[i];
}
// 处理 M 次操作
for (int op = 0; op < M; op++) {
int operationType;
cin >> operationType;
switch (operationType) {
case 1: {
// 查找-替换操作
int L1;
cin >> L1;
vector<int> searchSeq(L1);
for (int i = 0; i < L1; i++) {
cin >> searchSeq[i];
}
int L2;
cin >> L2;
vector<int> replaceSeq(L2);
for (int i = 0; i < L2; i++) {
cin >> replaceSeq[i];
}
// 查找并替换第一个匹配的子序列
bool found = false;
for (int i = 0; i <= sequence.size() - L1; i++) {
if (equal(sequence.begin() + i, sequence.begin() + i + L1, searchSeq.begin())) {
sequence.erase(sequence.begin() + i, sequence.begin() + i + L1);
sequence.insert(sequence.begin() + i, replaceSeq.begin(), replaceSeq.end());
found = true;
break;
}
}
break;
}
case 2: {
// 插入平均数操作
vector<int> newSequence;
for (size_t i = 0; i < sequence.size() - 1; i++) {
newSequence.push_back(sequence[i]);
if ((sequence[i] + sequence[i + 1]) % 2 == 0) {
newSequence.push_back((sequence[i] + sequence[i + 1]) / 2);
}
}
newSequence.push_back(sequence.back());
sequence = newSequence;
break;
}
case 3: {
// 翻转操作
int l, r;
cin >> l >> r;
reverse(sequence.begin() + l - 1, sequence.begin() + r);
break;
}
}
}
// 输出最终结果
for (size_t i = 0; i < sequence.size(); i++) {
cout << sequence[i];
if (i < sequence.size() - 1) cout << " ";
}
return 0;
}
l2-3
熊猫生活需要几个山头的问题
一天只有246060s,考虑差分数组,把时间按秒变成线性的,在每个panda的开始时间+1,结束时间-1,这就是差分数组,求前缀和就能得到每个时间点有几只panda,找最大值就好了
(比赛时做完了,没有存代码)
l2-4
非常简单的dfs,熟悉搜索的会觉得思路很清晰,满足条件的数不多,从高位往低位搜索下一个可能的数,注意要把不整除的剪枝
l3-1
n只有500,可以用floyd算法预处理出所有点间最短路,在转移的时候顺便维护一下路上心情值之和即可,注意最后9分点的问题是当找到点i,j之间有相同长度的最短路时,路上心情值之和是这两条路走最小
点击查看代码
#include<bits/stdc++.h>
//#define INF 0x3f3f3f3f
#define lowbit(x) = ((x)& - (x))
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>=c;a--)
#define x first
#define y second
using namespace std;
typedef long long ll;
const int INF = 1e9;
const int N = 503;
int n,b,m,k;
int w1[N][N],w2[N][N];
int ans1[N],ans2[N];
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int u,v,x,y;
cin>>b>>n>>m>>k;
rep(i,1,n){
rep(j,1,n){
w1[i][j] = w1[j][i] = INF;
if(i == j)w1[i][j] = 0;
}
}
rep(i,1,m){
cin>>u>>v>>x>>y;
w1[u][v] = w1[v][u] = x;
w2[u][v] = w2[v][u] = y;
}
rep(k,1,n){
rep(i,1,n){
rep(j,1,n){
if(w1[i][j]>=w1[i][k]+w1[k][j]){
if(w1[i][j]==w1[i][k]+w1[k][j]){
w2[i][j] = max(w2[i][j],w2[i][k]+w2[k][j]);
}
else{
w2[i][j] = w2[i][k]+w2[k][j];
}
w1[i][j] = w1[i][k]+w1[k][j];
w2[j][i] = w2[i][j];
w1[j][i] = w1[i][j];
}
//if(w1[i][k]+w1[k][j]<=b)w2[i][j] = max(w2[i][j],w2[i][k]+w2[k][j]);
}
}
}
int p,cnt1 = 0,cnt2 = 0,ma = 0;
rep(i,1,k){
cnt1 = cnt2 = 0;
ma = 0;
cin>>p;
rep(j,1,n){
if(w1[p][j]<=b && j!=p){
ans1[++cnt1] = j;
ma = max(ma,w2[p][j]);
}
}
sort(ans1+1,ans1+cnt1+1);
rep(j,1,cnt1){
if(w2[p][ans1[j]] == ma )ans2[++cnt2] = ans1[j];
}
if(cnt1 == 0){
cout<<"T_T\n";
continue;
}
//cout<<cnt1<<'\n';
rep(j,1,cnt1-1)cout<<ans1[j]<<' ';cout<<ans1[cnt1]<<'\n';
rep(j,1,cnt2-1)cout<<ans2[j]<<' ';cout<<ans2[cnt2]<<'\n';
}
//cout<<w2[7][5];
return 0;
}
l3-2
就是要找到每个点对整张图dist之和然后乘以权值
一开始一直在想能不能dp或者公式之类的,最后想到其实就是前缀和
考虑a[i][j]是坐标(i,j)对(1,1)的dist,求a数组前缀和s
那么s[i][j]就是一个ij矩阵里(1,1)的dist之和
nm的图中点(x,y)可以以x行和y列把矩阵分割成4个小矩阵,(x,y)是这4个矩阵的角的位置,用前缀和求和在减去x行和y列重复计算了的点就是(x,y)对整张图的距离
dis[x][y] = s[x][y] + s[x][m-y+1] + s[n-x+1][y] + s[n-x+1][m-y+1] - (((x-1)x+(y-1)y + (n-x)(n-x+1)+(m-y)(m-y+1))/2)
点击查看代码
#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define lowbit(x) = ((x)& - (x))
#define rep(a,b,c) for(int a=b;a<=c;a++)
#define per(a,b,c) for(int a=b;a>=c;a--)
#define x first
#define y second
using namespace std;
typedef long long ll;
int n,m;
ll calc(int x,int y,vector<vector<ll>> & s){
ll res = 0;
res += s[x][y] + s[x][m-y+1] + s[n-x+1][y] + s[n-x+1][m-y+1];
res -= ((x-1)*x+(y-1)*y + (n-x)*(n-x+1)+(m-y)*(m-y+1))/2;
return res;
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n>>m;
vector<vector<ll>> dis(n+2,vector<ll>(m+2)),s(n+2,vector<ll>(m+2)),a(n+2,vector<ll>(m+2));
rep(i,1,n){
rep(j,1,m)cin>>a[i][j];
}
rep(i,0,n)s[i][0] = 0;
rep(j,0,m)s[0][j] = 0;
rep(i,1,n){
rep(j,1,m){
s[i][j] = s[i-1][j] + s[i][j-1] - s[i-1][j-1] + max(i-1,j-1);
}
}
rep(i,1,n){
rep(j,1,m){
dis[i][j] = calc(i,j,s);
}
}
rep(i,1,n){
rep(j,1,m - 1)cout<<a[i][j] * dis[i][j]<<' ';cout<<a[i][m] * dis[i][m]<<'\n';
}
return 0;
}

浙公网安备 33010602011771号