8VC Venture Cup 2016 - Elimination Round (626A,626B,626C(二分),626D(概率))

Robot Sequence

题目连接:

http://codeforces.com/problemset/problem/626/A

解题思路:

We can simulate Calvin’s path on each substring, and check if he returns to the origin.

Runtime: O(n3)

AC代码:

#include <bits/stdc++.h>
using namespace std;

int main(){
    int n;
    string str;
    while(~scanf("%d",&n)){
        cin>>str;
        int ans = 0,x,y;
        for(int i = 0; i < n; i++){
            for(int j = i; j < n; j++){
                x = 0;y = 0;
                for(int k = i; k <= j; k++){
                    if(str[k] == 'U')
                        y++;
                    if(str[k] == 'D')
                        y--;
                    if(str[k] == 'L')
                        x--;
                    if(str[k] == 'R')
                        x++;
                }
                if(x == 0 && y == 0)
                    ans++;
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

Cards

题目连接:

http://codeforces.com/problemset/problem/626/B

解题思路:

Note that if we have exactly one card of each color, we can always make all three options (by symmetry). Thus, if we have at least one of each color, or at least two of each of two colors, we can make all three options. The remaining cases are: if we only have one color, that’s the only possible final card; if we have one of each of two colors, we can only make the third color; if we have at least two of one color and exactly one of a second, we can only make the second or third color (e.g. sample 2).

Runtime: O(1)

AC代码:

#include <bits/stdc++.h>
using namespace std;

int dp[205][205][205];

int solve(int b,int g,int r){
    if(b<0 || g<0 || r<0)
        return 0;
    if(b+g+r == 1){
        if(b == 1)
            return 1;
        else if(g == 1)
            return 2;
        else
            return 4;
    }
    if(dp[b][g][r] != -1)
        return dp[b][g][r];
    int ans = 0;
    if(b >= 1 && g >= 1)
        ans |= solve(b-1,g-1,r+1);
    if(g >= 1 && r >= 1)
        ans |= solve(b+1,g-1,r-1);
    if(b >= 1 && r >= 1)
        ans |= solve(b-1,g+1,r-1);
    if(b >= 2)
        ans |= solve(b-1,g,r);
    if(g >= 2)
        ans |= solve(b,g-1,r);
    if(r >= 2)
        ans |= solve(b,g,r-1);
    return dp[b][g][r] = ans;
}

int main(){
    int n;
    string str;
    while(~scanf("%d",&n)){
        cin>>str;
        memset(dp,-1,sizeof(dp));
        int cnta = 0,cntb = 0,cntc = 0;
        for(int i = 0; i < n; i++){
            if(str[i] == 'B')
                cnta++;
            else if(str[i] == 'G')
                cntb++;
            else
                cntc++;
        }
        int ans = solve(cnta,cntb,cntc);
        string s = "";
        if(ans & 1)
            s += 'B';
        if(ans & 2)
            s += 'G';
        if(ans & 4)
            s += 'R';
        printf("%s\n",s.c_str());
    }
    return 0;
}


Block Towers

题目连接:

http://codeforces.com/problemset/problem/626/C

解题思路:

There are a variety of ways to do this problem. Here is one way: if the answer is X, there must be at least n multiples of 2 below X, at leastm multiples of 3 below X, and at least n + m multiples of 2 or 3 below X. These conditions are actually sufficient, so we need to find the smallest X such that , and . We can do this with a linear search, or with an explicit formula.

Runtime: O(1)

AC代码:

#include <bits/stdc++.h>
using namespace std;

int n,m;

bool solve(int x){
    if(x == -1)
        return false;
    int ns = x/2,ms = x/3,ss = x/6;
    int nn = n,mm = m;
    nn -= ns-ss;
    mm -= ms-ss;
    nn = max(0,nn);
    mm = max(0,mm);
    return ss >= nn+mm;
}

int main(){
    while(~scanf("%d%d",&n,&m)){
        int l = 0, r = 10000000;
        while(l <= r){
            int mid = (l+r)/2;
            if(solve(mid))
                r = mid-1;
            else
                l = mid+1;
        }
        printf("%d\n",l);
    }
    return 0;
}

Jerry's Protest

题目连接:

http://codeforces.com/problemset/problem/626/D

解题思路:

We do this algorithm in two phases: first, we compute the probability distribution of the difference between the winner and loser of each round. This takes O(n2) time. Then, we can iterate over the 2 differences which Andrew wins by and compute the probability that Jerry has a greater total using with suffix sums.

Runtime: O(n2 + amax2)

AC代码:

#include <bits/stdc++.h>
using namespace std;

typedef long long ll;
int a[2005], cnt[5010];
long long gre[5010];

int main(){
    int n;
    while(~scanf("%d", &n)){
        for (int i = 0; i < n; i++)
            scanf("%d", &a[i]);
        sort(a,a+n);
        for(int i = 0; i < n; i++){
            for(int j = i + 1; j < n; j++){
                int x = a[j] - a[i];
                cnt[x]++;
            }
        }
        ll sum = 0;
        for(int i = 5005; i >= 0; i--){
            gre[i] = sum;
            sum += cnt[i];
        }
        double ans = 0;
        for(int i = 0; i <= 5005; i++){
            for(int j = 0; j <= 5005; j++){
                if(i + j >= 5005)
                    continue;
                ans += (long double)cnt[i] * cnt[j] * gre[i + j];
            }
        }
        for(int i = 0; i < 3; i++)
            ans /= n * (n - 1)/2;
        printf("%.10lf\n",ans);
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值