Educational Codeforces Round 87 (Rated for Div. 2)【ABC1C2D】(题解)
涵盖知识点:解析几何、树状数组
比赛链接:传送门
A - Alarm Clock
题意: 一天要睡够\(a\)分钟,但是\(b\)分钟后有一个闹钟会使其醒来,他会把闹钟推迟到\(c\)分钟之后,然后花费\(d\)小时再次入睡。问要多久能够睡够。
题解: 模拟推公式
Accept Code:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int main(){
int t;cin>>t;
while(t--){
ll a,b,c,d;
cin>>a>>b>>c>>d;
if(b>=a){
cout<<b<<"\n";
continue;
}
if(d>=c){
cout<<-1<<"\n";
continue;
}
cout<<(a-b+c-d-1)/(c-d)*c+b<<"\n";
}
return 0;
}
B - Ternary String
题意: 给定的串仅含有\(1,2,3\)。问最短的字串使得同时存在这三种字符。
题解: 顺序扫描,在线更新。
Accept Code:
#include <bits/stdc++.h>
using namespace std;
int vis[3];
string s;
int main(){
int t;cin>>t;
while(t--){
memset(vis,0,sizeof vis);
cin>>s;
int ans=s.length()+1,n=0;
for(int i=0;i<s.length();i++){
while(n<s.length()&&(!vis[0]||!vis[1]||!vis[2])){
vis[s[n]-'1']++;
n++;
}
if(vis[0]&&vis[1]&&vis[2])ans=min(ans,n-i);
vis[s[i]-'1']--;
}
if(ans>s.length())cout<<"0\n";
else cout<<ans<<"\n";
}
return 0;
}
C1 - Simple Polygon Embedding
题意: \(n\)为偶数,\(2n\)个长度为\(1\)的线段构成一个正\(2n\)边形。问最小的正方形使得能够包裹住这个多边形。
题解: \(2n\)可被\(4\)整除。选两组对边与正方形重合显然最小。
Accept Code:
#include <bits/stdc++.h>
using namespace std;
const double pi=acos(-1);
int main(){
int t;cin>>t;
while(t--){
int n;
cin>>n;
printf("%.9lf\n",1/tan(pi/(n*2)));
}
return 0;
}
C2 - Not So Simple Polygon Embedding
题意: n$为奇数,\(2n\)个长度为\(1\)的线段构成一个正\(2n\)边形。问最小的正方形使得能够包裹住这个多边形。
题解: 设偏转角为\(x\),外接圆半径为\(l\),所求正方形的半边长为\(r\),可以得出\(r=l\times \cos x\),求导获得单调性\(r'=-\sin x\)。在\([0,\pi]\)导数小于0,所以长度单调递减。又根据对称性可以得到取到的最小值应该在\(x=\frac{\pi}{4n}\)时取到。
Accept Code:
#include <bits/stdc++.h>
using namespace std;
const double pi=acos(-1);
int main(){
int t;cin>>t;
while(t--){
int n;
cin>>n;
double a=pi/(n*2);
double r=1/sin(a);
a/=2;
printf("%.9lf\n",r*cos(a));
}
return 0;
}
D - Multiset
题意: 多重集合,初始化后可以选择增加新数字或者删除某个位置的数字。求操作完成后集合内剩下的数字。
题解: 树状数组维护每个数字的个数。通过前缀和判断该位置是哪个数字。
Accept Code:
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e6+10;
int c[maxn],n,q;
inline int lowbit(int x){return x&(-x);}
void add(int x){
while(x<=n){
c[x]++;
x+=lowbit(x);
}
}
void del(int x){
while(x<=n){
c[x]--;
x+=lowbit(x);
}
}
int query(int x){
int res=0;
while(x){
res+=c[x];
x-=lowbit(x);
}
return res;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cin>>n>>q;
for(int i=0,x;i<n;i++)cin>>x,add(x);
for(int i=0,x;i<q;i++){
cin>>x;
if(x>0) { add(x); continue;}
x=-x;
int l=1,r=n,ans;
while(l<=r){
int mid=(l+r)/2;
if(query(mid)>=x)ans=mid,r=mid-1;
else l=mid+1;
}
del(ans);
}
for(int i=1;i<=n;i++){
if(query(i)){
cout<<i<<"\n";
return 0;
}
}
cout<<"0\n";
return 0;
}