Codeforces Round #428 (Div. 2)题解

A:直接判断一下有没有8颗以上糖有就给8颗然后留下来没有就全给了

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
int a[105]
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 1; i <= n; i++)
        scanf("%d",&a[i]);
    int ans = 0;
    int i;
    int pre = 0;
    for(i = 1; i <= n; i++){
        pre = a[i]+pre;
        if(pre>=8){
            ans += 8;
            pre-=8;
        }
        else{
            ans += pre;
            pre = 0;
        }
        if(ans>=m)
            break;
    }
    if(ans>=m)
        printf("%d\n",i);
    else
        puts("-1");
    return 0;
}
B:先把4个的和3个都放中间然后剩下2个的和1个的判断一下就可以了


#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int mx = 40005;
int main(){
    int n,k,a;
    scanf("%d%d",&n,&k);
    int s1 = n,s2 = 2*n,q = 0,p = 0;
    for(int i = 1; i <= k; i++){
        scanf("%d",&a);
        while(a>=3){
            a-=4;
            s1--;
        }
        a>0?q+=a%2,p+=a/2:0;
    }
    (p<=s1+s2&&q<=s1*2+s2-p)||(p>s1+s2&&p*2+q<=s1*3+s2*2)?puts("YES"):puts("NO");
    //如果两个一样的个数小于等于s1+s2只要满足当p<=s2时 q<=s1*2+s2-p当p>s2时q<=2*(s1+s2-p)+p-s1=s1*2+s2-p
    //如果两个一样的个数大于s1+s2同理分情况讨论可以求出p*2+q<=s1*3+s2*2
    return 0;
}

C:求每一层一层的求到达最后叶子节点的概率然后就是概率乘于深度,所有总和加起来即可

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
const int mx = 1e5+5;
int out[mx];
vector<int>g[mx];
double deep[mx];
double ans = 0;
void dfs(int u,double d,double gai,int fa){
    deep[u] = d*gai;
    double len = g[u].size();
    if(len==1&&g[u][0]==fa)
        ans+=deep[u];
    if(u!=1)
        len--;
    for(auto v:g[u])
        if(v!=fa)
            dfs(v,d+1,gai/len,u);
}
int main(){
    int n;
    scanf("%d",&n);
    memset(out,0,sizeof(out));
    for(int i = 1; i < n; i++){
        int u,v;
        scanf("%d%d",&u,&v);
        g[v].push_back(u);
        g[u].push_back(v);
    }
    dfs(1,0,1,0);
    printf("%.10f\n",ans);
    return 0;
}


D:假设是i的倍数的数有c个那么gcd=i的答案sum[i] = c*2^c-1-sum[2*i]-sum[3*i]-....sum[n*i],因为里面包含了gcd等于2*i,3*i,...n*i的个数




然后求一下2到max(a[i])中的每一个sum[i]从最终的答案就是sima(i*sum[i])


#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long int ll;
const int mx = 1000005;
const ll mod = 1e9+7;
ll x[mx];
int a[200005];
int T[mx];
int cnt[mx];
ll  sum[mx];
int main(){
    x[0] = 0;
    x[1] = 1;
    int n;
    for(int i = 2; i < mx; i++)
        x[i] = x[i-1]*2%mod;
    scanf("%d",&n);
    int maxx = 1;
    for(int i = 1; i <= n; i++){
        scanf("%d",&a[i]);
        maxx = max(a[i],maxx);
        T[a[i]]++;
    }
    for(int i = 2; i <= maxx; i++)
        for(int j = i; j <= maxx; j+=i)
            cnt[i]+=T[j];
    for(int i = maxx; i >= 2; i--){
        sum[i] = cnt[i]*x[cnt[i]]%mod;
        for(int j = 2*i; j <= maxx; j+=i)
            sum[i] = ((sum[i]-sum[j])%mod+mod)%mod;
    }
    ll ans = 0;
    for(int i = 2; i <= maxx; i++)
        if(sum[i]){
            ans = (ans+sum[i]*i)%mod;
          //  cout<<sum[i]<<endl;
        }
    printf("%I64d\n",ans);
    return 0;
}

E:找出最大的完全图然后每个点平方m,最后的答案就是(m/ans)*(m/ans)*ans*(ans-1)/2

判断这个点加入完全图或者不加入完全图求最大的ans

注意当剩下的点全部加入时候还不能大于ans时候就不用再算下去了,如果这一步不做会超时

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
using namespace std;
int map[50][50];
int pre[50];
int ans = 0;
int n,m;
void dfs(int pos,int cnt){
    ans = max(ans,cnt);
    if(n-pos+cnt+1<=ans)   return;
    if(pos>n)   return;
    dfs(pos+1,cnt);
    int ok = 1;
    for(int i =0; i < cnt; i++)
        if(!map[pos][pre[i]]){
            ok = 0;
            break;
        }
    if(ok){
        pre[cnt++] = pos;
        dfs(pos+1,cnt);
    }
}
int main(){
    scanf("%d%d",&n,&m);
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            scanf("%d",&map[i][j]);
    ans = 0;
    dfs(1,0);
    printf("%.10f\n",0.5*m*m*(ans-1)/ans);
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值