Educational Codeforces Round 87 Rated for Div. 2
比赛链接 https://codeforces.com/contest/1354
比赛记录 https://blog.csdn.net/cheng__yu_/article/details/105395197
A. Alarm Clock
思路:读题读清楚就好了
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=4e4+10,mod=998244353;
int t;
ll a,b,c,d;
int main()
{
cin>>t;
while(t--)
{
cin>>a>>b>>c>>d;
if(a<=b)
{
cout<<b<<"\n";
continue;
}
if(c<=d)
{
puts("-1");
continue;
}
ll r=a-b;
ll t=c-d;
ll tt=r/t+(r%t==0?0:1);
ll ans=b+c*tt;
cout<<ans<<"\n";
}
return 0;
}
B. Ternary String
题意:找一个最短的区间同时包含 1、2、3
思路:第一眼看到题目是蒙的,完全没有想到要维护一个区间。想了一分钟,直接用预处理来做。结果就写了半天
- 可以维护一个左右区间记录一下 1、2、3的数量
- 也可以预处理一下,处理出每个位置后面 1、2、3出现的位置
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=5000+10,inf=2e9;
int t;
string s;
int cnt[3];
int main()
{
cin>>t;
while(t--)
{
cnt[0]=cnt[1]=cnt[2]=0;
cin>>s;
int n=s.size();
s="0"+s;
int now=1,ans=inf;
for(int i=1;i<=n;++i)
{
while(now<=n&&(cnt[0]==0||cnt[1]==0||cnt[2]==0))
cnt[s[now++]-'1']++;
if(cnt[0]&&cnt[1]&&cnt[2])
ans=min(ans,now-i);
cnt[s[i]-'1']--;
}
if(ans==inf) ans=0;
cout<<ans<<"\n";
}
return 0;
}
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+5,inf=0x3f3f3f3f;
int t;
char s[maxn];
int nxt[maxn][5];
int main()
{
cin>>t;
while(t--)
{
scanf("%s",s+1);
int n=strlen(s+1);
for(int j=1;j<=3;++j)
nxt[n][j]=inf;
for(int i=n-1;i>=0;--i)
{
for(int j=1;j<=3;++j)
nxt[i][j]=nxt[i+1][j];
int x=s[i+1]-'1'+1;
nxt[i][x]=i+1;
}
int ans=inf;
for(int i=1;i<=n;++i)
{
if(s[i]=='1')
{
int p1=inf,p2=inf;
p1=nxt[i][2];
if(p1!=inf)
p2=nxt[p1][3];
if(p2!=inf)
ans=min(ans,p2-i);
p1=nxt[i][3];
if(p1!=inf)
p2=nxt[p1][2];
if(p2!=inf)
ans=min(ans,p2-i);
}
else if(s[i]=='2')
{
int p1=inf,p2=inf;
p1=nxt[i][1];
if(p1!=inf)
p2=nxt[p1][3];
if(p2!=inf)
ans=min(ans,p2-i);
p1=nxt[i][3];
if(p1!=inf)
p2=nxt[p1][1];
if(p2!=inf)
ans=min(ans,p2-i);
}
else if(s[i]=='3')
{
int p1=inf,p2=inf;
p1=nxt[i][1];
if(p1!=inf)
p2=nxt[p1][2];
if(p2!=inf)
ans=min(ans,p2-i);
p1=nxt[i][2];
if(p1!=inf)
p2=nxt[p1][1];
if(p2!=inf)
ans=min(ans,p2-i);
}
}
if(ans==inf)
puts("0");
else
cout<<ans+1<<"\n";
}
return 0;
}
C1. Simple Polygon Embedding
题意:给定一个正 2n边形,求最小的外切正方形的面积。n恒为偶数
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=2e5+5,inf=0x3f3f3f3f;
const double PI=acos(-1.0);
int t,n;
int main()
{
cin>>t;
while(t--)
{
cin>>n;
long double ans=(long double)1.0/(2.0*sin(PI/(2.0*n)));
ans=ans*ans-0.25;
cout.precision(10);
cout <<fixed;
cout<<2*sqrt(ans)<<"\n";
}
return 0;
}
C2. Not So Simple Polygon Embedding
题意:给定一个正 2n边形,求最小的外切正方形的面积。n恒为奇数
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=1e5+5,inf=0x3f3f3f3f;
const long double PI=acos(-1.0);
int t;
long double n;
int main()
{
cout<<fixed<<setprecision(10);
cin>>t;
while(t--)
{
cin>>n;
long double ans=cos(PI/(4.0*n))/(sin(PI/(2.0*n)));
cout<<ans<<"\n";
}
return 0;
}
D. Multiset
#include <bits/stdc++.h>
#define ls (rt<<1)
#define rs (rt<<1|1)
#define ll long long
using namespace std;
const int maxn=1e6+10,mod=1e9+7,inf=1e9;
int n,q,x;
int st[maxn<<2];
void Insert(int rt,int l,int r,int p)
{
if(l==r)
{
st[rt]++;
return;
}
int mid=l+r>>1;
if(p<=mid) Insert(ls,l,mid,p);
else Insert(rs,mid+1,r,p);
st[rt]=st[ls]+st[rs];
}
void Delete(int rt,int l,int r,int rnk)
{
if(l==r)
{
st[rt]--;
return;
}
int mid=(l+r)>>1;
if(st[ls]>=rnk) Delete(ls,l,mid,rnk);
else Delete(rs,mid+1,r,rnk-st[ls]);
st[rt]=st[ls]+st[rs];
}
int query(int rt,int l,int r)
{
if(l==r)
return l;
int mid=l+r>>1;
if(st[ls])
return query(ls,l,mid);
else
return query(rs,mid+1,r);
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;++i)
{
scanf("%d",&x);
Insert(1,1,n,x);
}
while(q--)
{
scanf("%d",&x);
if(x>0) Insert(1,1,n,x);
else Delete(1,1,n,-x);
}
int ans;
if(st[1]==0) ans=0;
else ans=query(1,1,n);
printf("%d",ans);
return 0;
}
#include <bits/stdc++.h>
#define ls (rt<<1)
#define rs (rt<<1|1)
#define ll long long
using namespace std;
const int maxn=1e6+10,mod=1e9+7,inf=1e9;
int n,q,x;
int c[maxn];
int lowbit(int x)
{
return x&-x;
}
void add(int p,int v)
{
for(int x=p;x<=n;x+=lowbit(x))
c[x]+=v;
}
int getsum(int p)
{
int res=0;
for(int x=p;x>0;x-=lowbit(x))
res+=c[x];
return res;
}
int Search(int rnk)
{
int l=1,r=n;
while(l<r)
{
int mid=(l+r)>>1;
if(getsum(mid)>=rnk)
r=mid;
else
l=mid+1;
}
return l;
}
int main()
{
scanf("%d%d",&n,&q);
for(int i=1;i<=n;++i)
{
scanf("%d",&x);
add(x,1);
}
while(q--)
{
scanf("%d",&x);
if(x>0) add(x,1);
else add(Search(-x),-1);
}
printf("%d\n",getsum(n)==0?0:Search(1));
return 0;
}
E. Graph Coloring
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=5000+10,maxm=1e5+10;
int n,m,n1,n2,n3;
int head[maxn],cnt;
struct Edge
{
int nxt,to;
}edges[maxm<<1];
void add(int u,int v)
{
edges[++cnt].to=v;
edges[cnt].nxt=head[u];
head[u]=cnt;
}
int c1[maxn],c2[maxn],c[maxn],belong[maxn];
int dp[maxn][maxn],visit[maxn],rev[maxn];
int tot;
void dfs(int u,int co)
{
visit[u]=true;
c[u]=co;
belong[u]=tot;
if(co==1) c1[tot]++;
else c2[tot]++;
for(int i=head[u];i!=-1;i=edges[i].nxt)
{
int v=edges[i].to;
if(!visit[v])
dfs(v,3-co);
if(c[u]+c[v]!=3)
{
puts("NO");
exit(0);
}
}
}
int main()
{
memset(head,-1,sizeof(head)),cnt=0;
scanf("%d%d%d%d%d",&n,&m,&n1,&n2,&n3);
for(int i=1;i<=m;++i)
{
int u,v;
scanf("%d%d",&u,&v);
add(u,v);
add(v,u);
}
for(int i=1;i<=n;++i)
if(!visit[i])
tot++,dfs(i,1);
dp[0][0]=true;
for(int i=1;i<=tot;++i)
{
for(int j=c1[i];j<=n2;++j)
dp[i][j]|=dp[i-1][j-c1[i]];
for(int j=c2[i];j<=n2;++j)
dp[i][j]|=dp[i-1][j-c2[i]];
}
if(!dp[tot][n2])
{
puts("NO");
return 0;
}
while(tot)
{
if(n2>=c1[tot])
rev[tot]=dp[tot-1][n2-c1[tot]];
if(rev[tot]) n2-=c1[tot];
else n2-=c2[tot];
tot--;
}
puts("YES");
for(int i=1;i<=n;++i)
{
if(rev[belong[i]]) c[i]=3-c[i];
if(c[i]==2) putchar('2');
else if(n1) putchar('1'),n1--;
else putchar('3');
}
return 0;
}