Codeforces Round #428 (Div. 2)

来源:互联网 发布:php 身份证号获取性别 编辑:程序博客网 时间:2024/06/06 03:28

A:水题

#include<iostream>#include<algorithm>#include<cstdio>#include<vector>#include<cstring>#include<set>using namespace std;typedef long long ll;#define inf 0x3f3f3f3fconst int mx = 1e4+5,mod = 1e9+7;int n,m,a[mx];int main(){    scanf("%d%d",&n,&m);    int ans = 0;    for(int i=1;i<=n;i++) scanf("%d",a+i);    for(int i=1;i<=n;i++){        if(a[i]>8) { a[i+1]+= a[i]-8, a[i] = 8;  }        m -= a[i];        ans++;        if(m<=0) break;    }    if(m>0) puts("-1");    else printf("%d\n",ans);    return 0;}
B:先考虑将中间四个填满,不能刚好填满的先放着,然后在将前后填满,剩一个的也先留着,然后最后再去将这些填剩下的四个空座拿去填,1和2做好弄成差不多,就能尽可能的多放。

#include<iostream>#include<algorithm>#include<cstdio>#include<vector>#include<cstring>#include<set>using namespace std;typedef long long ll;#define inf 0x3f3f3f3fconst int mx = 1e4+5,mod = 1e9+7;int n,m,a[mx/10],id[4];int main(){    scanf("%d%d",&n,&m);    for(int i=1;i<=m;i++) scanf("%d",a+i);    int cnt = 2*n;    for(int i=1;i<=m;i++){        int v = a[i]/4;        if(n>=v) { n -= v; a[i] = a[i]%4; continue; }        a[i] = a[i] - n*4, n = 0;    }    for(int i=1;i<=m&&cnt;i++){        int v = a[i]/2;        if(a[i]&1) id[1]++;        if(cnt>=v) { cnt -= v,a[i] = 0; continue; }        a[i] = a[i] - cnt*2 , cnt = 0;    }    if(cnt){        if(cnt+2*n>=id[1]) puts("YES");        else puts("NO");        return 0;    }    for(int i=1;i<=m;i++){        if(a[i]>=4) {  puts("NO");  return 0;  }        id[a[i]]++;    }    n -= id[3];    if(id[2]>id[1]){        int v = id[2] - id[1];        v = v/2;        id[2] -= v;        id[1] += 2*v;    }    int x = min(id[1],id[2]);    n -= x , id[1] -= x , id[2] -= x;    n -= id[2];    n -= (id[1]+1)/2;    puts(n<0? "NO":"YES");    return 0;}


C:不管怎么走最后都是到叶子的,所以暴力就行了。

#include<iostream>#include<algorithm>#include<cstdio>#include<vector>#include<cstring>#include<set>using namespace std;typedef long long ll;#define inf 0x3f3f3f3fconst int mx = 1e5+5,mod = 1e9+7;int n,m,in[mx],deep[mx];double val[mx];vector<int>vec[mx];void dfs(int x,int f){    for(int i=0;i<vec[x].size();i++){        int son = vec[x][i];        if(son==f) continue;        deep[son] = deep[x] + 1;        val[son] = val[x]*1.0/(vec[x].size()-1);        dfs(son,x);    }}int main(){    scanf("%d",&n);    int a,b;    deep[1] = 0;    for(int i=1;i<n;i++){        scanf("%d%d",&a,&b);        in[a]++ , in[b]++;        vec[a].push_back(b);        vec[b].push_back(a);    }    vec[1].push_back(0);    val[1] = 1;    dfs(1,0);    double ans = 0;    for(int i=1;i<=n;i++){        if(in[i]==1) ans += val[i]*deep[i];    }    printf("%.7f\n",ans);    return 0;}

D:容斥之前需要先算出一个公式那就是k*2^(k-1),k代表x的倍数个数,就是公约数包含x的最多个数,这个根据组合项前后项合并很容易得到。然后就是直接容斥啦。

#include<iostream>#include<algorithm>#include<cstdio>#include<vector>#include<cstring>#include<set>using namespace std;typedef long long ll;#define inf 0x3f3f3f3fconst int mx = 1e6+5,mod = 1e9+7;int n,m,val[mx],cnt[mx],a[mx];typedef long long ll;int main(){    val[0] = 1;    ll ans = 0;    scanf("%d",&n);    for(int i=1;i<=n;i++) val[i] = 2*val[i-1]%mod;    for(int i=1;i<=n;i++) scanf("%d",&m),cnt[m]++;    for(int i=mx;i>=2;i--){        int p = i,sum = 0;        while(p<mx) sum +=cnt[p],p += i;        p = i+i;        a[i] = (1ll*sum*val[sum-1])%mod;        while(p<mx) a[i] = (a[i]-a[p]+mod)%mod, p += i;        ans = (ans+1ll*a[i]*i)%mod;    }    printf("%I64d\n",ans);    return 0;}





原创粉丝点击