Codeforces Round #418 (Div. 2) ABCD

本文分享了一次编程比赛的心得体会,并详细解析了几道题目,包括构造序列问题、数列匹配问题、字母染色问题及圆集合划分问题的解决思路与代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个小时做了三道题…第四道结束的时候wxl给我讲了一下贪心做法…当时看到题目吓虚了压根不敢写…结果也不是特别麻烦


【A】

An abandoned sentiment from past

构造一个序列,如果序列只能严格上升输出No,否则输出Yes
好像很可做的样子…大家自己YY吧,我这题被hack了艹


【B】

An express train to reveries

给两个数列,每个数列只能改动一个数字,使最终两个数列完全相同,输出改动后的数列。
分类讨论…好像很可做的样子…大家自己YY吧,我这题又被hack了艹


【C】

An impassioned circulation of affection

额这题没被hack,这是我唯一真正A掉的题233…
枚举每个数字,dp[k][cnt]表示字母k可以染色cnt次所能get到的最长连续字母串。O(26n^2)暴力扫一遍就可以处理出来…

终于可以上个代码了

//C
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
const int mxn=1505;
char s[mxn],ch;
int n,q,c;
int a[mxn],dp[28][mxn];
int main()
{
    int i,j,x,k;
    scanf("%d",&n);
    scanf("%s",s+1);
    scanf("%d",&q);
    fo(i,1,n) a[i]=s[i]-'a'+1;
    fo(k,1,26)
      fo(i,1,n)
      {
          int cnt=0;
          for(j=i;j>=1;j--)
          {
              if(a[j]!=k) cnt++;
              dp[k][cnt]=max(dp[k][cnt],i-j+1);
          }
      }
    fo(k,1,26)
      fo(i,1,n)
        if(!dp[k][i]) dp[k][i]=dp[k][i-1];
    while(q--)
    {
        scanf("%d",&x);
        cin>>ch;
        c=ch-'a'+1;
        printf("%d\n",dp[c][x]);
    }
    return 0;
}

【D】

An overnight dance in discotheque

给出一堆不相交的圆…分成两个集合,最大化两个集合圆面积异或并的和

如果一个圆覆盖一个小圆,那么大圆向小圆连边,拓扑排序一发后可以发现这些圆套圆可以变成很多个森林,把每个森林拿出来单独考虑。

考虑贪心,深度为1,深度为2的圆要放在两个集合中,下面深度奇数的圆减去,深度偶数的圆加上即可。

//CF D. An overnight dance in discotheque
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define pi acos(-1)
#define eps 1e-10
#define ll long long
#define M(a) memset(a,0,sizeof a)
#define fo(i,j,k) for(i=j;i<=k;i++)
using namespace std;
queue <int> q;
const int mxn=1005;
double ans;
int n,cnt,du[mxn],step[mxn],head[mxn];
struct edge {int to,next;} f[mxn*mxn]; 
inline void add(int u,int v)
{
    f[++cnt].to=v,f[cnt].next=head[u],head[u]=cnt;
}
struct circle
{
    double x,y,r;
}c[mxn];
inline double dis(circle a,circle b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
inline double calc(circle a)
{
    return pi*a.r*a.r;
}
inline void topsort()
{
    int i,j;
    fo(i,1,n) if(!du[i]) q.push(i);
    while(!q.empty())
    {
        int u=q.front();q.pop();
        for(i=head[u];i;i=f[i].next)
        {
            int v=f[i].to;
            du[v]--;
            if(!du[v]) step[v]=step[u]+1,q.push(v);
        }
    }
    fo(i,1,n)
      if(!step[i] || step[i]&1) ans+=calc(c[i]);
      else ans-=calc(c[i]);
}
int main()
{
    int i,j;
    scanf("%d",&n);
    fo(i,1,n)
      scanf("%lf%lf%lf",&c[i].x,&c[i].y,&c[i].r);
    fo(i,1,n)
      fo(j,1,i-1)
        if(dis(c[i],c[j])<c[i].r+c[j].r-eps)
        {
            if(c[i].r>c[j].r) add(i,j),du[j]++;
            else add(j,i),du[i]++;
        }
    topsort();
    printf("%.8lf\n",ans);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值