2023广东省大学生程序设计竞赛 比赛总结

本文回顾了2023年7月14日举行的广东省大学生程序设计竞赛,详细解析了D、K、E、I、B、F、M、J等题目,采用贪心、爆搜、Trie树等算法。作者在赛后总结了自己的经验与教训。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

比赛时间:7月14日
比赛链接:2023年广东省赛
过题数:8/13

比赛情况

题解

D

b i − a i b_i-a_i biai由大到小排序, d e l i > 0 del_i>0 deli>0表示让 i i i没有邻居更优。由于最多的没有邻居的人数可以求出,因此贪心地计入贡献即可。注意细节。

//
// Created by zjun on 2023/7/14.
//
#include <bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define x first
#define y second
using namespace std;
const int N = 2e6 + 10;
int n, m;
struct node {
   
   
    int a, b;
    bool operator<(const node& x) const {
   
   
        return b - a > x.b - x.a;
    }
} p[N];
void solve() {
   
   
    cin >> n >> m;
    int sum = 0;
    for (int i = 1; i <= n; i++) {
   
   
        cin >> p[i].a >> p[i].b;
        sum += p[i].a;
    }

    if (n == 1) {
   
   
        cout << p[1].b << "\n";
        return;
    }


    sort(p + 1, p + 1 + n);
    int mx = 0, delta = 0;
    for (int i = 1; i <= m - n && i <= n && p[i].b - p[i].a > 0; i++) {
   
   
        delta += p[i].b - p[i].a;
        mx = i;
    }
    if (mx != n - 1) {
   
   
        cout << sum + delta << "\n";
    } else {
   
   
        int ans1 = sum + delta - (p[mx].b - p[mx].a);
        int ans2 = sum + delta + (p[n].b - p[n].a);
        cout << max(ans1, ans2) << "\n";
    }
}

signed main() {
   
   
    ios::sync_with_stdio(false); cin.tie(0);
    int T = 1; cin >> T;
    while (T--) {
   
   
        solve();
    }
    return 0;
}

K

由于 n , m , k ≤ 6 n,m,k\leq 6 n,m,k6,直接爆搜。

#include<cstdio>
#include<algorithm>
#define maxn 10
using namespace std;

struct position
{
   
   
	int x,y,fl;
	position(){
   
   }
	position(int _x,int _y,int _fl)
	{
   
   
		x=_x;y=_y;fl=_fl;
	}
}pos[maxn];
int t,n,m,k,ans;
int mp[maxn][maxn];
int d[4][2]={
   
   {
   
   1,0},{
   
   0,1},{
   
   -1,0},{
   
   0,-1}};

void clear()
{
   
   
	for(int i=1;i<=n;++i)
	for(int j=1;j<=m;++j)
	mp[i][j]=0;
}

void dfs(int res)
{
   
   
	ans=min(ans,res);
	for(int i=1;i<=k;++i)
	{
   
   
		int x=pos[i].x,y=pos[i].y,fl=pos[i].fl;
		if(fl)
		continue;
		for(int j=0;j<4;++j)
		{
   
   
			int xx=x+d[j][0],yy=y+d[j][1];
			int nx=xx+d[j][0],ny=yy+d[j][1];
			if(xx<1||xx>n||yy<1||yy>m)
			continue;
			if(nx<1||nx>n||ny<1||ny>m)
			continue;
			if(!mp[xx][yy])
			continue;
			if(mp[nx][ny])
			continue;
			//eat
			int lst=mp[xx][yy];
			pos[i]=position(nx,ny,0);
			pos[lst].fl=1;
			mp[x][y]=0;
			mp[nx][ny]=i;
			mp[xx][yy]=0;
			dfs(res-1);
			pos[i]=position(x,y,0);
			pos[lst].fl=0;
			mp[x][y]=i;
			mp[nx][ny]=0;
			mp[xx][yy]=lst;
		}
	}
}

int main()
{
   
   
	scanf("%d",&t);
	while(t--)
	{
   
   
		scanf("%d%d%d",&n,&m,&k);
		for(int i=1;i<=k;++i)
		{
   
   
			int x,y;
			scanf("%d%d",&x,&y);
			mp[x][y]=i;
			pos[i]=position(x,y,0);
		}
		ans=k;
		dfs(k);
		printf("%d\n",ans);
		clear();
	}
	return 0;
}

E

看到前缀想到Trie树。

将模式串加入到Trie树中,统计结点被经过的次数。因为要使得答案字典序最小,因此从根节点开始,从 z z z a a a走到底,回溯时若该节点的 c n t > 1 cnt>1 cnt>1且还可以删字符串,则将其删到只剩一串,否则从根节点到该节点的路径即为答案。

#include<cstdio>
#include<cstring>
#define maxn 1000005
using namespace std;

int t,n,k,m,findans;
int ndnum,go[maxn][26],cnt[maxn],del[maxn],fa[maxn
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值