coderforces-#428三道水题

本文解析了三道编程题目,包括糖果分配问题、座位安排问题及树形结构中期望距离的最大值问题。通过具体示例代码展示了如何使用贪心算法、DFS等方法解决问题。

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

A - Arya and Bran :水题,wa了一发。

题意:A给B糖果,每天可以给a[i]个,最多给8个,剩下的可以存下下来之后给。

求:A给Bk个糖果最少的天数(1-n)天以内才能给。

所以直接求解就好了。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define siz 100005

using namespace std;
int n,k;
int gp[siz];
void solve(){
    int ans = 0;
    int t;
    for(int i=1;i<=n;i++){
        if(gp[i]>=8){
            ans+=8;
            gp[i+1] += gp[i] - 8;
        }
        else ans += gp[i];
        if(ans>=k||gp[i]==0){
            cout<<i<<endl;
            break;
        }
    }
    if(ans<k){
        cout<<-1<<endl;
    }
}
int main()
{
    while(~scanf("%d%d",&n,&k)){
        for(int i=1;i<=n;i++){
            scanf("%d",&gp[i]);
        }
        solve();
    }
    return 0;
}
第二题: B - Game of the Rows 题意:

给有n行座位,每行有8个座位,12相邻,34相邻,45相邻,56相邻,78相邻。

给m个团体,每个团体有a[i]个人,不同团体的人不能坐在一块,问能否让这所有的人坐下,是输出yes,否则no。

思路:贪心:如果某个团体超过四个人,则按照4人一组坐3456,如果座位不够,再按两人一组坐12或者78,否则就无法坐下。按死人一组分完之后,剩余的人会是3,2,1三种情况。如果是3个人,尽可能先做4,个人的座位,如果座位不够则要坐两个人的位置,并且要占两个,再不够。。无法坐下。

如果是2个人,先坐2的位置,不够再坐4的位置,此时,4的位置旁边还能坐一个人的位置,所以tx++,表示还能坐一个人。再不够,则两人分开坐tx的位置,再不够。。无法坐下。如果是1个人,先坐一个人的位置tx,如果不够,坐4个人的位置,旁边可以坐2个人,所以2人位置要+1,再不够,坐两人位置。还不够。。无法坐下。

#include <iostream>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define siz 100005
#include <queue>
using namespace std;
int n,k;
int gp[siz];
priority_queue<int>que;
void solve(){
    int flag = 1;
    //int i=1,j=1;
    int seat2 = 2*n;
    int seat4 = n;
    int tx = 0;
    while(!que.empty()){
        int x = que.top();
        que.pop();
        int y = x/4;
        int mo = x%4;
        if(seat4>=y){
            seat4 -= y;
        }
        else{
            y-=seat4;
            seat4 = 0;
            if(seat2>=2*y){
                seat2 -= 2*y;
            }
            else{
                flag = 0;
                break;
            }
        }
        if(mo==3){
            if(seat4>0) seat4 -= 1;
            else{
                if(seat2>1){
                    seat2 -=2;
                }
                else{
                    flag = 0;
                    break;
                }
            }
        }
        if(mo==2){
            if(seat2>0){
                seat2 -=1;
            }
            else{
                if(seat4>0){
                    seat4 -= 1;
                    tx++;
                }
                else if(tx>1){
                    tx -= 2;
                }
                else{
                    flag = 0;
                    break;
                }
            }
        }
        if(mo==1){
            if(tx>0){
                tx-=1;
            }
            else if(seat4>0){
                seat4 -=1;
                seat2 +=1; 
            }
            else if(seat2>0){
                seat2 -=1;
                //seat2 +=1;
            }
            else{
                flag =0;
                break;
            }
        }
    }
    if(flag){
        cout<<"YES"<<endl;
    }
    else{
        cout<<"NO"<<endl;
    }
}
int main()
{
    while(~scanf("%d%d",&n,&k)){
        while(!que.empty()) que.pop();
        for(int i=1;i<=k;i++){
            scanf("%d",&gp[i]);
            que.push(gp[i]);
        }
        solve();
    }
    return 0;
}

第三题: C - Journey

给n个节点的树(m-1条边),相邻两点之间的距离是1,一人从1节点出发,不能往回走,从该节点到其他与该节点 的节点的 概率是一样的。(相当于,如果这个节点有3个节点可以走,那么走每个节点的概率就是1/3)。问:该人能走最远的距离的期望值是多少。

思路:最远当然 是到达叶子节点。所以期望E(x) = dis[a1]*p[a1]+....。就是每一个叶子节点到根节点的距离乘以概率。概率就是根节点到达上一个节点的概率乘以上个节点到这个节点的概率。深搜一遍就行了。

#include <iostream>
#include<string.h>
#include<algorithm>
#include<stdio.h>
#define siz 100005
const int maxn = 100000;
typedef long long LL;
using namespace std;
struct Edge
{
    int to,w,next;
} edges[maxn*3];
int n,tot,q,k;
int head[maxn+5],num[maxn+5];
int d[maxn+5],cot,cnt;
double ans;
void Addedge(int x,int y,int w)
{
    edges[++tot].to = y, edges[tot].w = w;
    edges[tot].next = head[x], head[x] = tot;
    num[x]++;
}
void dfs(int x,int fa,double y)
{
    int ok = 1,nu=num[x];
    if(fa!=-1) nu--;
    double yy = 1.0/nu*y;
    for(int i=head[x]; i!=-1; i=edges[i].next)
    {
        int to = edges[i].to;
        if(to==fa) continue;
        d[to] = d[x] + edges[i].w, ok = 0;
        dfs(to,x,yy);
    }
    if(ok)
    {
        ans+=y*d[x]*1.0;
    }
}
int main()
{
    int x,y;
    while(~scanf("%d",&n))
    {
        tot = 0;
        for(int i=1; i<=n; i++) head[i] = -1,num[i]=0;
        for(int i=1; i<n; i++)
        {
            scanf("%d %d",&x,&y);
            Addedge(x,y,1);
            Addedge(y,x,1);
        }
        cnt = cot = ans = 0;
        d[1] = 0;
        dfs(1,-1,1.0);
        if(n==1) ans = 0;
        printf("%.15f\n",ans);
    }
    return 0;
}















评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值