PDF中文题面
PDF题解
C CCPC
赛时拿到的纸质版题面这个题是A题,所以先写的这个。想着签到题应该很简单,直接输出了
min(c/3,p)
,没有考虑CCPCCPC
这种情况,wa了以后很着急,没有想好正确的公式是怎样的,试了很多次
后来特判了c<3||p==0
的情况,cout << min( (c-3)/2+1, p);
题解
统计字符串S中C和P字符的个数cntC,cntP。
若 cntC<3 或 cntP<1 则答案为0。
否则答案为min(⌊ (cntC−1)/2 ⌋,cntP)。
时间复杂度O(|S|)。
AC代码
#include<bits/stdc++.h>
using namespace std;
int T=1;
void solve(){
string s;
cin >> s;
int c=0, p=0;
for(int i=0;i<s.size();i++){
if(s[i]=='C') c++;
else if(s[i]=='P') p++;
}
if(c<3||p<1){
cout <<"0\n";
}
else{
cout << min( (c-3)/2+1, p);
}
}
int main()
{
// cin >> T;
while(T--) solve();
}
A 盒子
当时被题面误导,将xy分别对应长宽都判断了,扩大了输出YES的范围,wa了一次之后一直不敢交,过了H题才提交,提交之后才看到讨论区发布的提醒
题解
给出三维坐标都与空间直角坐标系O−xyz的三条轴平行的长方体盒子的底面z坐标z0,高度h,底面对角线坐标(u0, v0), (u1,v1) 和 q 个点 (xi,yi,zi),问每个点是否在盒子内。
AC代码
#include<bits/stdc++.h>
#define YES cout<<"YES\n";
#define NO cout<<"NO\n";
using namespace std;
int T=1;
void solve(){
int z0,h,u0,v0,u1,v1;
int q;
cin >> z0 >> h >> u0 >> v0 >> u1 >> v1;
cin >> q;
while(q--){
int x,y,z;
cin >> x >> y >> z;
if( z<=z0+h && z>=z0 &&
x<=max(u0,u1) && x>=min(u0,u1) &&
y<=max(v0,v1) && y>=min(v0,v1)
) YES
else NO
}
}
int main()
{
// cin >> T;
while(T--) solve();
}
H 平方根
首先想到 n 个 √1 相加一定大于等于 √n,由于题意要将1变为0,可以想到111的情况下 (√1+√1)=2 > √3,但是1111会有 (√1+√1)=2 < (1+√2)。可以推导当有奇数个1在一起时,把所有偶数位的1变成0可以得到最大值;当有偶数个1在一起时,把除了最后一位以外所有的偶数位1变成0可以得到最大值
在写代码之前先二分了 √2 的值到1e-11的精度,然后const double g2=1.41421356233;
题解
每一段连续的1之间是独立的,我们只需要关心一段连续的1的结果。
可以证明对于一段连续的1,最优策略是将其划分成多个单独的1 以及可能余下的连续两个1。
具体来说,对于k个连续的1,如果k是奇数,最优策略是将其划分为 (k+1)/2 个单独的1,答案为 (k+1)/2 ;否则最优策略是将其划分为 k/2−1个单独的1和两个连续的1,答案为 k/2−1+√2。
时间复杂度O(|s|)。
AC代码
#include<bits/stdc++.h>
using namespace std;
const double g2=1.41421356233;
int T=1;
void solve(){
string s;
cin >> s;
double ans=0;
int cnt=0;
for(int i=0;i<s.size();i++){
if(s[i]=='1'){
cnt++;
}else if(cnt>0){
if(cnt%2){
ans+=(cnt+1)/2;
}else{
ans+=(cnt-2)/2+g2;
}
cnt=0;
}
}
if(cnt>0 && cnt%2){
ans+=(cnt+1)/2;
}else if(cnt>0 && cnt%2==0){
ans+=(cnt-2)/2+g2;
}
printf("%.10lf\n",ans);
}
int main()
{
// cin >> T;
while(T--) solve();
}
补充:二分求 √2 代码
#include<bits/stdc++.h>
using namespace std;
int T=1;
void solve(){
double l=1;
double r=2;
while(r-l>1e-11){
double mid=(l+r)/2;
if(mid*mid>2) r=mid;
else l=mid;
}
printf("%.11lf",l);
}
int main()
{
// cin >> T;
while(T--) solve();
}
L题M题待补充
最后贴一个提交记录纪念一下吧,没多久就要退役了