Codeforces Round #428 (Div. 2)

博主分享了在Codeforces Round #428 (Div. 2)比赛中的经历,指出长时间未参赛导致手感生疏。详细解析了三个题目:A. Arya and Bran的模拟思路,C. Journey的DFS路径搜索及对题意理解的重要性,B. Game of the Rows的贪心策略和审题关键。总结了比赛中容易忽视的细节和坑点,强调了审题和细心读题的重要性。

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

好久都没打cf了,这次明显感觉手生了不少

 

A. Arya and Bran

 

思路:模拟,从前往后模拟送的糖数,若不大于8则全送,否则只送8个剩余保留,送够为止,最后判断一下即可。

其实这次主要就是审题的问题,题目中有一句“before the end”,如果将其直接理解为倒序赠送,那么一上来就是一发wa。

于是赶紧临时改了一波题意

 

 

/*
Author Owen_Q
*/

#include <bits/stdc++.h>

using namespace std;

const int maxn = 110;

int a[maxn];

int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        for(int i=0;i<n;i++)
        {
            scanf("%d",&a[i]);
        }
        int t=0;
        int ct;
        int leave = 0;
        for(ct=0;ct<n;ct++)
        {
            t++;
            leave += a[ct];
            if(leave > 8)
            {
                leave -=8;
                k -= 8;
            }
            else
            {
                k -= leave;
                leave = 0;
            }
            if(k <=0)
            {
                break;
            }
        }
        if(ct==n)
        {
            printf("-1\n");
        }
        else
        {
            printf("%d\n",t);
        }
    }
    return 0;
}

 


C. Journey

思路:这题,典型的dfs寻找路径,由于是n点n-1边,则类似于最小生成树,不会成环,一开始还担心这个,以及只有一个顶点这两个问题,改了很长时间,后来发现这两种情况根本不需要单独考虑。

这题的坑点或许就在路径期望上了,还是需要细心读题,一开始是求总路径长度除以总路径数,后来才发现原来是不同树的深度,加权比重不同,需要每次单独处理,这样就会有大量的运算出现精度误差,与题目给的精度相吻合才十分合理

 

/*
Author Owen_Q
*/

#include <bits/stdc++.h>

using namespace std;

const int maxn = 1e5+10;

vector <int> ne[maxn];
//bool before[maxn];
bool city[maxn];

double sumlen;
//long long road;
double pi;

void dfs(int id,long long len,double p)
{
    int nelen = ne[id].size();
    city[id] = true;
    int nct = 0;
    for(int i=0;i<nelen;i++)
    {
        if(!city[ne[id][i]])
        {
            nct ++;
        }
    }
    if(nct>0)
    {
        double np = p / (double) (nct);
        for(int i=0;i<nelen;i++)
        {
            if(!city[ne[id][i]])
            {
                //before[id] = true;
                dfs(ne[id][i],len+1,np);
            }
        }
    }
    else
    {
        sumlen += len * p;
        //cout << id << " " << len << " " << p << endl;
    }
    /*if(!before[id])
    {
        sumlen += len;
        //road++;
    }*/
    /*city[id] = false;
    before[id] = false;*/
    return ;
}

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        memset(city,false,sizeof(city));
        //memset(before,false,sizeof(before));
        for(int i=1;i<=n;i++)
        {
            ne[i].clear();
        }
        sumlen = 0;
        //road = 0;
        pi = 1.0;
        for(int i=0;i<n-1;i++)
        {
            int a,b;
            scanf("%d%d",&a,&b);
            ne[a].push_back(b);
            ne[b].push_back(a);
        }
        dfs(1,0,1.0);
        //double re = (double)(sumlen) / (double)(road);
        /*if(road!=0)
        {
            re = (double)(sumlen) / (double)(road);
        }
        else
        {
            re = 0;
        }*/
        //cout << sumlen << " " << road << " ";
        printf("%.15lf\n",sumlen);
    }
    return 0;
}

 

 

 

 

 

 

B. Game of the Rows

 

思路:这题看似简单,就是寻找一种排座位的贪心思路,实则坑点十足啊

首先,还是审题,中间位置的图不是白画的,看图才能更直观得理解

这题,比较简单的思路就是先将能坐满4个人的座位坐满,将所有队模4,简化问题,并保证剩余4座数不小于0,将多余的人强制加在2座上

由于这题时间较为宽松,排个序会使问题更加简单

然后简化的问题分四种情况,座位分为三种:四座,两座和剩两空以上的四座(以下简称空座)

3人坐先往四座上排,一组一座;坐满则往二座上排,一组两座

2人坐先往两座上排,一组一座;坐满则往四座上排,一组一座,并产生一个空座;再做满则往空座上坐,一组两座

1人坐先往空座上坐,一组一座;坐满组往两座上座,一组一座;再坐满则往四座上排,一组一座,并产生一个空座

0人坐,解决
 

2人坐以及空座均为易忽略点,此题要想全确实不易啊

 

 

/*
Author Owen_Q
*/

#include <bits/stdc++.h>

using namespace std;

const int maxn = 110;

int a[maxn];

int main()
{
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        int sit4 = n;
        int sit2 = 2*n;
        int block = 0;
        for(int i=0;i<k;i++)
        {
            scanf("%d",&a[i]);
        }
        /*for(int i=0;i<k;i++)
        {
            cout << a[i] << endl;
        }*/
        for(int i=0;i<k;i++)
        {
            sit4 -= (a[i]/4);
            a[i] %= 4;
        }
        sort(a,a+k,greater<int>());
        if(sit4<0)
        {
            sit2 += sit4 * 2;
            sit4 = 0;
        }
        /*cout << "sit4" << sit4 << endl;
        for(int i=0;i<k;i++)
        {
            cout << a[i] << endl;
        }*/
        //int i;
        for(int i=0;i<k;i++)
        {
            if(a[i]==3)
            {
                if(sit4>0)
                {
                    sit4--;
                }
                else
                {
                    sit2 -= 2;
                }
            }
            else if(a[i]==2)
            {
                if(sit2>0)
                {
                    sit2--;
                }
                else
                {
                    if(sit4>0)
                    {
                        sit4--;
                        block++;
                    }
                    else
                    {
                        block -= 2;
                    }
                }
            }
            else if(a[i]==1)
            {
                if(block>0)
                {
                    block--;
                }
                else if(sit2>0)
                {
                    sit2--;
                }
                else
                {
                    sit4--;
                    block++;
                }
            }
            a[i] = 0;
            /*if(sit2<0)
            {
                sit2 = 0;
                sit4--;
            }
            if(sit2 == 0)
            {
                break;
            }*/
        }
        /*cout << "sit2" << sit2 << endl;
        for(int i=0;i<k;i++)
        {
            cout << a[i] << endl;
        }*/
        /*sit4 *= 2;
        for(int j=i;j<k;j++)
        {
            if(a[j]>0)
            {
                a[j] = 0;
                sit4--;
            }
        }*/
        /*cout << "sit4" << sit4 << endl;
        for(int i=0;i<k;i++)
        {
            cout << a[i] << endl;
        }*/
        if(sit2>=0&&sit4>=0&&block>=0)
        {
            printf("YES\n");
        }
        else
        {
            printf("NO\n");
        }
    }
    return 0;
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值