比赛时间:7月14日
比赛链接:2023年广东省赛
过题数:8/13
比赛情况
题解
D
将 b i − a i b_i-a_i bi−ai由大到小排序, 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,k≤6,直接爆搜。
#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