Divide by Zero 2017 and Codeforces Round #399 (Div. 1 + Div. 2, combined)

原创 2017年02月22日 20:25:47

这把比赛题目不错,然而打得太挫了。。来写一发题解

C. Jon Snow and his Favourite Number

基本上是暴力模拟,不过排序和异或要写O(1000)的。

#include <bits/stdc++.h>


using namespace std;

const int maxn = 100010;
int n,k,x;

int cnt[1024][2];

int main(){

    cin>>n>>k>>x;

    for(int i=0;i<n;i++){
        int num;
        scanf("%d",&num);
        cnt[num][0]++;
    }

    int cur = 0;
    int pre = 1;
    while(k--){
        swap(cur,pre);
        //sort

        for(int i=0;i<1024;i++){
            cnt[i][cur] = 0;
        }

        int p = 0;
        for(int i=0;i<1024;i++){
            cnt[i][cur] += cnt[i][pre]>>1;
            cnt[i^x][cur] += cnt[i][pre]>>1;

            if((cnt[i][pre])&1){
                if(p&1){
                    cnt[i][cur]++;
                }else{
                    cnt[i^x][cur]++;
                }
            }
            p+=cnt[i][pre];
        }


    }
    for(int i=1023;;i--){
        if(cnt[i][cur]){
            cout<<i<<" ";
            break;
        }
    }

    for(int i=0;;i++){
        if(cnt[i][cur]){
            cout<<i<<endl;
            break;
        }
    }
    return 0;
}

D. Jon and Orbs

考虑到每个orb是等价的,状态用当前已有多少个orb来表示。递推计算出来每天有1~k个orb的概率(题目要求的最大概率是1/2,递推到第100000天绝对够了),处理好p取1~1000的答案,再回答。

#include <bits/stdc++.h>


using namespace std;

double p_count[1010];

int ans[1010];

int main(){
    int k,q;
    cin>>k>>q;
    int p = 1;
    double target;
    for(int i=0;i<=k;i++){
        p_count[i] = 0;
    }

    p_count[0] = 1.0;
    for(int day = 1;p<=1000;day++){
        target = (p+0.0)/2000;
        for(int i=k;i>0;i--){
            double tmp = p_count[i-1] * ((k-i+1.0)/k);
            p_count[i] += tmp;
            p_count[i-1] -= tmp;
        }

        while(p_count[k] >= target){
            ans[p] = day;
            p++;
            target = (p+0.0)/2000;
            if(p>1000)break;
        }
    }


    while(q--){
        cin>>p;
        cout<<ans[p]<<endl;
    }
    return 0;
}

E. Game of Stones

很有意思的一个题。解题的关键是注意到一堆数量为1的石子和一堆数量为2的石子是等效的。因为这两种堆都只能够被拿一次。仔细分析我们会发现,石子的数量在1以上,相当于传统nim的1,石子的数量在1+2=3以上,相当于传统nim的2,石子的数量在1+2+3=6以上,相当于传统nim的3…把每堆数量转化一下,就是变成一个传统的nim博弈问题了。另外每堆上限仅60,据说可以搜索。

#include <bits/stdc++.h>

using namespace std;

#define ll long long

int cnt[66];

int a[66];

int main(){
    int n; 
    cin>>n;

    for(int i=0;i<n;i++){
        int num;
        scanf("%d",&num);
        cnt[num]++;
    }

    for(int i=1;i<=60;i++){
        a[i] = a[i-1] + i;
    }

    vector<int> p;
    for(int i=1;i<=60;i++){
        cnt[i] %= 2;
    }

    for(int i=1;i<=60;i++){
        if(cnt[i]){
            for(int j=1;j<=60;j++){
                if(a[j]>i){
                    cnt[j-1]++;
                    cnt[i]--;
                    break;
                }
            }
        }
    }

    int sum = 0;
    for(int i=1;i<=60;i++){
        while(cnt[i]--){
            sum ^= i;
        }
    }

    if(sum){
        puts("NO");
    }else{
        puts("YES");
    }

    return 0;
}

F. Barrels and boxes

组合数学问题。先说分母(总数),枚举酒的堆数i,由组合数学知识,相当于w个小球中间的w1个位置放i1个隔板,也就是求一个组合数,此时食物的堆数只能是i1~i+1,计算方法同酒,然后把它们乘起来。
分子(符合条件的情形数),也是枚举酒的堆数i,因为有高度要求,把酒的数量减去ih,再进行与分母一样的运算即可。

#include <bits/stdc++.h>

using namespace std;

#define ll long long

const ll mod = 1e9 + 7;

ll fac[100010];

//扩展欧几里德   
void ExEuclid(ll a,ll b,ll &x,ll &y,ll &q){  
    if(b==0){  
        x=1;y=0;q=a;  
        return;  
    }  
    ExEuclid(b,a%b,y,x,q);  
    y-=x*(a/b);  
}  

//逆元   
ll inv(ll num){  
    ll x,y,q;  
    ExEuclid(num,mod,x,y,q);  
    if(q==1)return (x+mod)%mod;  
}  

ll C(int n,int k){
    if(n<0 || k<0)return 0;
    if(n<k)return 0;
    ll res = fac[n];
    res *= inv(fac[k]);
    res %= mod;
    res *= inv(fac[n-k]);
    res %= mod;
    return res;
}

ll solve(int f,int w,int mn,int mx){
    if(w == 0 || f == 0)return 1;

    ll res = 0;
    // w -> i
    for(int i=mn;i<=mx;i++){
        ll t = C(w-1,i-1);
        if(i>1){
            res += t * C(f-1,i-2);
        }
        res += t * C(f-1,i-1) * 2;
        res += t * C(f-1,i);
        res %= mod;
    }
    res %= mod;
    return res;
}

int main(){
    fac[0] = 1;
    for(int i=1;i<=100000;i++){
        fac[i] = fac[i-1] * i;
        fac[i] %= mod;
    }

    int f,w,h;
    cin>>f>>w>>h;

    //p/q
    ll p = 0;
    ll q = 0;
    if( h == 0){
        p = solve(f,w,1,w);
        q = solve(f,w,1,w);
    }else{
        q = solve(f,w,1,w);

        for(int i=1;;i++){
            int ww = w - i*h;
            if(ww<i)break;
            p += solve(f,ww,i,i);
        }
        p %= mod;
        if(w == 0){
            p = 1;
            q = 1;
        }
    }

    ll ans = p * inv(q);
    ans %= mod;
    cout<<ans<<endl;
    return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。

ICM Technex 2017 and Codeforces Round #400 (Div. 1 + Div. 2, combined) E. The Holmes Children

E. The Holmes Children time limit per test 2 seconds memory limit per test 256 megabytes...
  • mystery_guest
  • mystery_guest
  • 2017年03月04日 18:40
  • 284

Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined)A+B

A. Gotta Catch Em’ All!time limit per test:1 secondmemory limit per test:256 megabytesinput:standard...
  • qq_33183401
  • qq_33183401
  • 2017年01月16日 17:12
  • 239

Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined) A. Gotta Catch Em' All!(水题)

题目链接:http://codeforces.com/contest/757/problem/AA. Gotta Catch Em’ All! time limit per test1 second...
  • qq_32866009
  • qq_32866009
  • 2017年01月13日 09:17
  • 200

【解题报告】Codeforces Round #401 (Div. 2)

简略的解题报告。
  • TRiddle
  • TRiddle
  • 2017年02月25日 17:55
  • 410

Codeforces Round #258 (Div. 2)-(A,B,C,D,E)

A:Game With Sticks 水题。。。每次操作,都会拿走一个横行,一个竖行。 所以一共会操作min(横行,竖行)次。 #include #include #include #include ...
  • rowanhaoa
  • rowanhaoa
  • 2014年07月25日 14:39
  • 1471

Codeforces Round #395 (Div. 2)(ABCD)

ps:打完这场cf才知道自己真的很菜,还是停留在AB题的水平,有时候CD其实很简单,但就是想不到,别人一眼看出而我就是想不到,有时候想到了点子上但就是突破不了 题目链接:  Codeforc...
  • qq_34731703
  • qq_34731703
  • 2017年02月03日 12:50
  • 488

Codecraft-17 and Codeforces Round #391 (Div. 1 + Div. 2, combined) C. Felicity is Coming!组合学+集合

题意:给出n组数,每组gi个数,每个数属于1~m,每个数可以变化但变化前相同的数变化后依然相同,变化前不同的速变化后依然不同,且可能不变,但经过变化后每组的每种数的个数不会变化,求变化的总方案数。 组...
  • ProLightsfxjh
  • ProLightsfxjh
  • 2017年01月14日 01:28
  • 569

Codeforces Round #254 (Div. 1)C. DZY Loves Colors(线段树经典操作/分块)

题目链接 C. DZY Loves Colors time limit per test 2 seconds memory limit per test 256 mega...
  • fouzhe
  • fouzhe
  • 2017年02月11日 15:17
  • 278

Intel Code Challenge Elimination Round (Div.1 + Div.2, combined) -- C. Destroying Array (并查集)

大体题意: 给你n 个数字,告诉你破坏每个数字的顺序,每次破坏后你要求一个线段,使得线段不包含破坏的点,并且线段上的值和最大? 思路: 正着删除感觉不好处理,就反过来求了,相当于从一个空序列往上...
  • aozil_yang
  • aozil_yang
  • 2016年10月02日 00:37
  • 372

Codeforces Round #460 (Div. 2) D. Substring(拓扑排序)

题目链接题意:有一个n个点m条边的有向图,每个节点有一个字母,路径的权值是路径上相同字母的最大个数。求最大的路径权值。思路:因为只有26个字母,所以直接假设其中一个字母为相同字母数最大的字母。枚举每一...
  • cyf199775
  • cyf199775
  • 2018年02月01日 13:55
  • 36
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:Divide by Zero 2017 and Codeforces Round #399 (Div. 1 + Div. 2, combined)
举报原因:
原因补充:

(最多只允许输入30个字)