codeforces Rockethon 2015

54 篇文章 0 订阅
53 篇文章 0 订阅

比赛链接:http://codeforces.com/contest/513


A. Game
time limit per test 2 seconds
memory limit per test 256 megabytes

Two players play a simple game. Each player is provided with a box with balls. First player's box contains exactly n1 balls and second player's box contains exactly n2 balls. In one move first player can take from 1 to k1 balls from his box and throw them away. Similarly, the second player can take from 1 to k2 balls from his box in his move. Players alternate turns and the first player starts the game. The one who can't make a move loses. Your task is to determine who wins if both players play optimally.

Input
The first line contains four integers n1, n2, k1, k2. All numbers in the input are from 1 to 50.

This problem doesn't have subproblems. You will get 3 points for the correct submission.

Output
Output "First" if the first player wins and "Second" otherwise.

Sample test(s)
input
2 2 1 2
output
Second
input
2 1 1 1
output
First
Note
Consider the first sample test. Each player has a box with 2 balls. The first player draws a single ball from his box in one move and the second player can either take 1 or 2 balls from his box in one move. No matter how the first player acts, the second player can always win if he plays wisely.


题目大意,两个人玩游戏,开始A的盒子有n1个球,B的盒子有n2个球,A先开始取球,A可以取1-k1个,B再取,B可以取1-k2个,直到一方没有球可取则另一方胜


题目分析:因为两个人都会选择最佳策略,那就都取1个,因为取的少剩的多可选择的余地更大,这样就与k1,k2无关了,比价一下n和m的大小即可,注意因为A先,所以n相等时A先取完则B胜


#include <cstdio>

int main()
{
    int n1, n2, k1, k2;
    scanf("%d %d %d %d", &n1, &n2, &k1, &k2);
    if(n1 > n2)
        printf("First\n");
    else
        printf("Second\n");
}


B1.B2. Permutations

time limit per test 2 seconds

memory limit per test 256 megabytes


You are given a permutation p of numbers 1, 2, ..., n. Let's define f(p) as the following sum:


Find the lexicographically m-th permutation of length n in the set of permutations having the maximum possible value of f(p).

Input
The single line of input contains two integers n and m (1 ≤ m ≤ cntn), where cntn is the number of permutations of length n with maximum possible value of f(p).

The problem consists of two subproblems. The subproblems have different constraints on the input. You will get some score for the correct submission of the subproblem. The description of the subproblems follows.

In subproblem B1 (3 points), the constraint 1 ≤ n ≤ 8 will hold.
In subproblem B2 (4 points), the constraint 1 ≤ n ≤ 50 will hold.
Output
Output n number forming the required permutation.

Sample test(s)
input
2 2
output
2 1
input
3 2
output
1 3 2
Note
In the first example, both permutations of numbers {1, 2} yield maximum possible f(p) which is equal to 4. Among them, (2, 1) comes second in lexicographical order.


题目大意:如题所给公式,求和最大的所有排列中的第m个


题目分析:yy,写出3和4时的各种情况,根据各数字出现的位置找规律,得到以下yy结论

拿m-1和1 2 3 ... n-1的二进制取与运算,结果为0则从左往右放,否则从右往左放


#include <iostream>
using namespace std;
long long m, n, ans[50];

int main() 
{
    cin >> n >> m;
    int l = 0, r = n - 1;
    for(int i = 1; i <= n; i++) 
    {
        if(i == n)
        {
            if((m - 1) & ((1ll << n) - 1)) 
                ans[r--] = i;
            else 
                ans[l++] = i;
        }
        else
        { 
            if((m - 1) & (1ll << (n - i - 1))) 
                ans[r--] = i;
            else 
                ans[l++] = i;
        }
    }
    for(int i = 0; i < n; i++) 
        cout << ans[i] << ' ';
    cout << endl;
}



G1. Inversions problem
time limit per test2 seconds
memory limit per test256 megabytes


You are given a permutation of n numbers p1, p2, ..., pn. We perform k operations of the following type: choose uniformly at random two indices l and r (l ≤ r) and reverse the order of the elements pl, pl + 1, ..., pr. Your task is to find the expected value of the number of inversions in the resulting permutation.

Input
The first line of input contains two integers n and k (1 ≤ n ≤ 100, 1 ≤ k ≤ 109). The next line contains n integers p1, p2, ..., pn — the given permutation. All pi are different and in range from 1 to n.

The problem consists of three subproblems. The subproblems have different constraints on the input. You will get some score for the correct submission of the subproblem. The description of the subproblems follows.

In subproblem G1 (3 points), the constraints 1 ≤ n ≤ 6, 1 ≤ k ≤ 4 will hold.
In subproblem G2 (5 points), the constraints 1 ≤ n ≤ 30, 1 ≤ k ≤ 200 will hold.
In subproblem G3 (16 points), the constraints 1 ≤ n ≤ 100, 1 ≤ k ≤ 109 will hold.
Output
Output the answer with absolute or relative error no more than 1e - 9.

Sample test(s)
input
3 1
1 2 3
output
0.833333333333333
input
3 4
1 3 2
output
1.458333333333334
Note
Consider the first sample test. We will randomly pick an interval of the permutation (1, 2, 3) (which has no inversions) and reverse the order of its elements. With probability , the interval will consist of a single element and the permutation will not be altered. With probability  we will inverse the first two elements' order and obtain the permutation (2, 1, 3) which has one inversion. With the same probability we might pick the interval consisting of the last two elements which will lead to the permutation (1, 3, 2) with one inversion. Finally, with probability  the randomly picked interval will contain all elements, leading to the permutation (3, 2, 1) with 3 inversions. Hence, the expected number of inversions is equal to .


题目大意:一个1-n的排列,可做k次操作,每次选两个数(可以相同)然后倒排他们包括他们之间的所有数,求最后总的逆序对个数的期望


题目分析:因为G1数据很小,暴力深搜一下就行了,分母就是分段的种类个数即1+2+3+...+n,分子是逆序对个数


#include <cstdio>
#include <algorithm>
using namespace std;
int n, a[105];
double all;

double sum(int num)
{
    double tmp = 0.0;
    for(int i = 1; i <= num; i++)
        tmp += i;
    return tmp;
}

double cal(int k)
{
    if(k == 0)
    {
        double tmp = 0;
        for(int i = 0; i < n; i++)
            for(int j = i + 1; j < n; j++)
                if(a[i] > a[j])
                    tmp++;
        return tmp;
    }
    double ans = 0;
    for(int i = 0; i < n; i++)
    {
        for(int j = i + 1; j <= n; j++)
        {
            reverse(a + i, a + j);
            ans += cal(k - 1);
            reverse(a + i, a + j);
        }
    }
    return ans / all;
}

int main()
{
    int k;
    scanf("%d %d", &n, &k);
    for(int i = 0; i < n; i++)
        scanf("%d", &a[i]);
    all = sum(n);
    printf("%.10f\n", cal(k));
}




G2. Inversions problem
time limit per test2 seconds
memory limit per test256 megabytes


You are given a permutation of n numbers p1, p2, ..., pn. We perform k operations of the following type: choose uniformly at random two indices l and r (l ≤ r) and reverse the order of the elements pl, pl + 1, ..., pr. Your task is to find the expected value of the number of inversions in the resulting permutation.

Input
The first line of input contains two integers n and k (1 ≤ n ≤ 100, 1 ≤ k ≤ 109). The next line contains n integers p1, p2, ..., pn — the given permutation. All pi are different and in range from 1 to n.

The problem consists of three subproblems. The subproblems have different constraints on the input. You will get some score for the correct submission of the subproblem. The description of the subproblems follows.

In subproblem G1 (3 points), the constraints 1 ≤ n ≤ 6, 1 ≤ k ≤ 4 will hold.
In subproblem G2 (5 points), the constraints 1 ≤ n ≤ 30, 1 ≤ k ≤ 200 will hold.
In subproblem G3 (16 points), the constraints 1 ≤ n ≤ 100, 1 ≤ k ≤ 109 will hold.
Output
Output the answer with absolute or relative error no more than 1e - 9.

Sample test(s)
input
3 1
1 2 3
output
0.833333333333333
input
3 4
1 3 2
output
1.458333333333334
Note
Consider the first sample test. We will randomly pick an interval of the permutation (1, 2, 3) (which has no inversions) and reverse the order of its elements. With probability , the interval will consist of a single element and the permutation will not be altered. With probability  we will inverse the first two elements' order and obtain the permutation (2, 1, 3) which has one inversion. With the same probability we might pick the interval consisting of the last two elements which will lead to the permutation (1, 3, 2) with one inversion. Finally, with probability  the randomly picked interval will contain all elements, leading to the permutation (3, 2, 1) with 3 inversions. Hence, the expected number of inversions is equal to .


题目大意:同上,只是数据不同


题目分析:数据变大,暴搜肯定超时,当k大的时候有很多重复计算,考虑用dp来记忆化存储,当第k次操作pi > pj时,dp[i][j][k] = 1,否则dp[i][j][k] = 0


#include <cstdio>
#include <cstring>
using namespace std;
int a[35], n, k;
double dp[35][35][205];

double sum(int num)  
{  
    double tmp = 0.0;  
    for(int i = 1; i <= num; i++)  
        tmp += i;  
    return tmp;  
}  

int main()
{
    memset(dp, 0, sizeof(dp));
    scanf("%d %d", &n, &k);
    for(int i = 0; i < n; i++)
        scanf("%d", &a[i]);
    for(int i = 0; i < n; i++)
        for(int j = i; j < n; j++)
            if(a[i] > a[j])
                dp[i][j][0] = 1;
    double p = sum(n);
    for(int t = 1; t <= k; t++)
        for(int st = 0; st < n; st++)
            for(int ed = st; ed < n; ed++)
                for(int x = 0; x < n; x++)
                    for(int y = x; y < n; y++)
                    {
                        int tx = x, ty = y;
                        if(st <= x && x <= ed)
                            tx = st + ed - x;
                        if(st <= y && y <= ed)
                            ty = st + ed - y;
                        if(ty >= tx)
                            dp[x][y][t] += dp[tx][ty][t - 1] / p;
                        else
                            dp[x][y][t] += (1 - dp[ty][tx][t - 1]) / p;
                    }
    double ans = 0;
    for(int i = 0; i < n; i++)
        for(int j = i; j < n; j++)
            ans += dp[i][j][k];
    printf("%.10f\n", ans);
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值