2024ccpc女生赛题解
补题链接:
https://codeforces.com/gym/105487
考场上写的A,C,H,L,M
下来补E,K
A 盒子#
水题。
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstdio>
#include <cstring>
#define LL long long
using namespace std;
// const int N=100005;
int z0,h,u0,v0,u1,v1,q;
int main() {
scanf("%d %d %d %d %d %d",&z0,&h,&u0,&v0,&u1,&v1);
if(u1<u0) swap(u0,u1);
if(v1<v0) swap(v0,v1);
scanf("%d",&q);
while(q--) {
int x,y,z;
scanf("%d %d %d",&x,&y,&z);
if(z0<=z&&z<=z0+h&&u0<=x&&x<=u1&&v0<=y&&y<=v1) puts("YES");
else puts("NO");
}
return 0;
}
C#
注意ccpccpc这种就好。
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
int main() {
string s;
cin>>s;
int cntp=0,cntc=0;
for(int i=0;i<s.length();i++) {
if(s[i]=='P') cntp++;
if(s[i]=='C') cntc++;
}
cout<<min(cntp,(cntc-1)/2);
return 0;
}
//ccpccpc
H#
注意到如果是3个数,中间放0收益
推广到更多位亦然,也就是说,奇数个数,都拆成单独的1(偶数位都变0),收益一定最高。
偶数个数,先不看最后一位,前面的为奇数个,按上一步处理。最后这位显然置为1收益更高。因为
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
int main() {
string s;
cin >> s;
int cnt = 0;
int ans = 0, cnt2 = 0;
for (int i = 0; i < s.length(); i++) {
if (s[i] == '0') {
if (!cnt) continue;
if (cnt % 2) {
ans += ((cnt + 1) / 2);
} else {
ans += (cnt / 2) - 1;
cnt2++;
}
cnt = 0;
} else {
cnt++;
}
}
if (cnt) {
if (cnt % 2) {
ans += (cnt + 1) / 2;
} else {
ans += cnt / 2 - 1;
cnt2++;
}
}
printf("%.10lf", (double) ans + (double) cnt2 * sqrt(2));
return 0;
}
L 拼图#
A至少四个,注意到,B=C,设中间的D组成
可以暴力枚举
注意特判D=0的情况。
(考场因此wa了一发)
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
int main() {
int T;
scanf("%d",&T);
while(T--) {
int a,b,c,d;
scanf("%d %d %d %d",&a,&b,&c,&d);
if(a<4) {
puts("0");
continue;
}
int mi=min(b,c);
int ans=4;
for(int i=1;i<=d;i++) {
for(int j=1;j<=d/i;j++) {
if(d>=i*j&&mi>=i+j) {
ans=max(ans,(i+2)*(j+2));
}
}
}
ans=max(ans,(mi+2)*2);
printf("%d\n",ans);
}
return 0;
}
M 覆盖一棵树#
贪心,对于每个点
具体可以先dfs一遍求深度,对每个点,维护其子树中深度最小的叶子的深度。
最后用
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
const int N=2e5+5;
const int inf=1e9;
int n;
vector<int>g[N];
int fa[N],dep[N];
int mi[N];//
void dfs(int x) {
dep[x]=dep[fa[x]]+1;
for(auto y:g[x]) {
dfs(y);
if(mi[y]==inf) mi[x]=dep[y];
else
mi[x]=min(mi[x],mi[y]);
}
}
int main() {
int T;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
for(int i=1;i<=n;i++) {
mi[i]=inf;
dep[i]=0;
g[i].clear();
}
for(int i=2;i<=n;i++) {
scanf("%d",&fa[i]);
g[fa[i]].push_back(i);
}
dfs(1);
int ans=0;
for(int i=2;i<=n;i++) {
if(mi[i]!=inf) {
ans=max(mi[i]-dep[i]+1,ans);
}
}
ans=max(mi[1]-dep[1],ans);
printf("%d\n",ans);
}
return 0;
}
E 重心树#
注意
和重心关系不大,一个简单的构造,手模几个样例就能发现规律。
倒着枚举:
并查集维护连通块以及连通块的根,根就是连通块中最小编号的点。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cmath>
#include <vector>
using namespace std;
const int N=2e5+5;
#define LL long long
int n;
int fa[N];
int find(int x) {
return fa[x]==x?x:fa[x]=find(fa[x]);
}
int c[N];
vector<int>p[N];
void merge(int x,int y) {
int fx=find(x),fy=find(y);
if(fx>fy) swap(fx,fy);//id小的做根
fa[fy]=fx;
}
bool vis[N];
int main() {
int T;
scanf("%d",&T);
while(T--) {
scanf("%d",&n);
for(int i=1;i<=n;i++) {
fa[i]=i;
vis[i]=0;
p[i].clear();
}
for(int i=1;i<=n;i++) {
scanf("%d",&c[i]);
if(c[i]==0)
continue;
for(int j=1,x;j<=c[i];j++) {
scanf("%d",&x);
p[i].push_back(x);
}
}
for(int i=n;i;i--) {
for(int j=0;j<c[i];j++) {
int x=find(p[i][j]);
printf("%d %d\n",i,x);
merge(i,x);
}
}
}
return 0;
}
K 小凯的省奖之梦#
(考场上根本没读这题)
大模拟,在暴力的基础上优化即可,就是考验码力
暴力想法是,两层循环,枚举买几个p,几个q,然后去check加上这些分后是否能拿到省奖,
算一下复杂度,
check是 nlogn,但由于要多次排序,常数挺大。
t飞
第一次优化,二分q。在第22个点TLE。
第二次优化,发现可以分开处理两个学期的得奖情况,
AC代码:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
const int N = 505;
int rk[N];
int n;
struct Stu {
int id;
string nam;
int a1, a2, b1, b2, c1, c2;//zhi ,de ,ti
int sum1, sum2;
int prize;//奖项分
} s[N];
vector<Stu> sav[101];
vector<Stu> v1;
bool cmp1(Stu x, Stu y) {
return x.nam < y.nam;
}
char str[30];
Stu kk;
int fir, sec, thi;
int m, q, p;
void get_rk(vector<Stu> v) {
v.push_back(kk);
sort(v.begin(), v.end(), cmp1);
int cnt = 0;
for (auto x: v) {
rk[x.id] = ++cnt;
}
}
bool cmp2(Stu x, Stu y) {
if (x.sum1 == y.sum1) {
return x.a1 == y.a1 ? rk[x.id] < rk[y.id] : x.a1 > y.a1;
} else {
return x.sum1 > y.sum1;
}
}
bool cmp3(Stu x, Stu y) {
if (x.sum2 == y.sum2) {
return x.a2 == y.a2 ? rk[x.id] < rk[y.id] : x.a2 > y.a2;
} else {
return x.sum2 > y.sum2;
}
}
bool cmp4(Stu x, Stu y) {
if (x.prize == y.prize) {
if (x.sum1 + x.sum2 == y.sum1 + y.sum2) {
return x.a1 + x.a2 == y.a1 + y.a2 ? rk[x.id] < rk[y.id] : x.a1 + x.a2 > y.a1 + y.a2;
} else {
return x.sum1 + x.sum2 > y.sum1 + y.sum2;
}
} else {
return x.prize > y.prize;
}
}
bool cmp_z1(Stu x, Stu y) {
return x.a1 > y.a1;
}
bool cmp_z2(Stu x, Stu y) {
return x.a2 > y.a2;
}
int rk_zhi[N];//智yu排序
int score1, score2, score3;
void sinister1(vector<Stu> &v, int add, int fir, int sec, int thi) {
kk.a1 += add;
kk.sum1 += add;
v.push_back(kk);
sort(v.begin(), v.end(), cmp_z1);
int nowrank = 1;
for (int i = 0; i < n; i++, nowrank++) {
if (i > 0 && v[i].a1 == v[i - 1].a1) {
rk_zhi[v[i].id] = rk_zhi[v[i - 1].id];
} else
rk_zhi[v[i].id] = nowrank;
}
sort(v.begin(), v.end(), cmp2);
nowrank = 0;
for (auto &it: v) {
nowrank++;
it.prize = 0;
if (fir && rk_zhi[it.id] <= score1) {
it.prize += 15;
fir--;
continue;
}
if (sec && rk_zhi[it.id] <= score2) {
it.prize += 10;
sec--;
continue;
}
if (thi && rk_zhi[it.id] <= score3) {
it.prize += 5;
thi--;
continue;
}
}
kk.a1 -= add;
kk.sum1 -= add;
}
//拷贝
bool check(vector<Stu> v, int add, int fir, int sec, int thi) {
for (int i = 0; i < n; i++) {
if (kk.id == v[i].id) {
v[i].a2 += add;
v[i].sum2 += add;
break;
}
}
sort(v.begin(), v.end(), cmp_z2);
int nowrank = 1;
for (int i = 0; i < n; i++, nowrank++) {
if (i > 0 && v[i].a2 == v[i - 1].a2) {
rk_zhi[v[i].id] = rk_zhi[v[i - 1].id];
} else
rk_zhi[v[i].id] = nowrank;
}
sort(v.begin(), v.end(), cmp3);
nowrank = 0;
for (auto &it: v) {
nowrank++;
if (fir && rk_zhi[it.id] <= score1) {
it.prize += 15;
fir--;
continue;
}
if (sec && rk_zhi[it.id] <= score2) {
it.prize += 10;
sec--;
continue;
}
if (thi && rk_zhi[it.id] <= score3) {
it.prize += 5;
thi--;
continue;
}
}
sort(v.begin(), v.end(), cmp4);
bool ok = 0;
nowrank = 0;
for (auto &it: v) {
nowrank++;
if (it.id == kk.id) {
if (nowrank <= m) ok = 1;
break;
}
}
return ok;
}
int main() {
scanf("%d", &n);
kk.nam = "crazyzhk";
for (int i = 1; i <= n; i++) {
scanf("%s %d %d %d %d %d %d", str, &s[i].a1, &s[i].b1, &s[i].c1, &s[i].a2, &s[i].b2, &s[i].c2);
s[i].nam = str;
s[i].id = i;
s[i].sum1 = s[i].a1 + s[i].b1 + s[i].c1;
s[i].sum2 = s[i].a2 + s[i].b2 + s[i].c2;
if (s[i].nam == kk.nam) {
kk.a1 = s[i].a1;
kk.a2 = s[i].a2;
kk.b1 = s[i].b1;
kk.b2 = s[i].b2;
kk.c1 = s[i].c1;
kk.c2 = s[i].c2;
kk.id = i;
kk.sum1 = s[i].sum1;
kk.sum2 = s[i].sum2;
} else {
v1.push_back(s[i]);
}
}
get_rk(v1);
fir = floor(0.15 * (double) n);
sec = floor(0.25 * (double) n);
thi = floor(0.35 * (double) n);
score1 = floor(0.25 * (double) n);
score2 = floor(0.45 * (double) n);
score3 = floor(0.75 * (double) n);
bool flg = 0;
int ans = 1e8;
scanf("%d %d %d", &m, &p, &q);
for (int i = 0; i + kk.a1 <= 100; i++) {
sav[i] = v1;
sinister1(sav[i], i, fir, sec, thi);
int L = 0, R = 100 - kk.a2;
while (L <= R) {
int mid = (L + R) >> 1;
if (check(sav[i], mid, fir, sec, thi)) {
flg = 1;
ans = min(ans, i * p + mid * q);
R = mid - 1;
} else {
L = mid + 1;
}
}
}
if (flg) {
printf("%d", ans);
} else {
puts("Surely next time");
}
return 0;
}
作者:AuroraKelsey
出处:https://www.cnblogs.com/AuroraKelsey/p/18539458
版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了