2016 Multi-University Training Contest 7

15 篇文章 2 订阅
13 篇文章 0 订阅

HDU【5810】——Balls and Boxes


Time Limit: 2000/1000 MS (Java/Others)Memory Limit:65536/65536 K (Java/Others)
Problem Description

Mr. Chopsticks is interested in random phenomena, and he conducts an experiment to study randomness. In the experiment, he throws n balls into m boxes in such a manner that each ball has equal probability of going to each boxes. After the experiment, he calculated the statistical variance V as

V=i=1m(XiX)2m

where Xi is the number of balls in the ith box, and X is the average number of balls in a box.
Your task is to find out the expected value of V.

Input

The input contains multiple test cases. Each case contains two integers n and m (1 <= n, m <= 1000 000 000) in a line.
The input is terminated by n = m = 0.

Output

For each case, output the result as A/B in a line, where A/B should be an irreducible fraction. Let B=1 if the result is an integer.

Sample Input

2 1
2 2
0 0

Sample Output

0/1
1/2

Hint

In the second sample, there are four possible outcomes, two outcomes with V = 0 and two outcomes with V = 1.

Author

SYSU

比赛的时候扔给队友一个二项分布的期望是E(x) = npq,就没有管,然后就。。。。, V=n(m1)m2

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

int main()
{
    LL n,m;

    while(~scanf("%lld %lld",&n,&m) &&(n||m))
    {
        LL fz = n*(m-1);

        LL fm = m*m;

        LL g =__gcd(fz,fm);

        printf("%lld/%lld\n",fz/g,fm/g);
    }
    return 0;
}

HDU【5813】——Elegant Construction


Time Limit: 4000/2000 MS (Java/Others)Memory Limit: 65536/65536 K (Java/Others)

Special Judge

Problem Description

Being an ACMer requires knowledge in many fields, because problems in this contest may use physics, biology, and even musicology as background. And now in this problem, you are being a city architect!
A city with N towns (numbered 1 through N) is under construction. You, the architect, are being responsible for designing how these towns are connected by one-way roads. Each road connects two towns, and passengers can travel through in one direction.

For business purpose, the connectivity between towns has some requirements. You are given N non-negative integers a1 .. aN. For 1 <= i <= N, passenger start from town i, should be able to reach exactly ai towns (directly or indirectly, not include i itself). To prevent confusion on the trip, every road should be different, and cycles (one can travel through several roads and back to the starting point) should not exist.

Your task is constructing such a city. Now it’s your showtime!

Input

The first line is an integer T (T <= 10), indicating the number of test case. Each test case begins with an integer N (1 <= N <= 1000), indicating the number of towns. Then N numbers in a line, the ith number ai (0 <= ai < N) has been described above.

Output

For each test case, output “Case #X: Y” in a line (without quotes), where X is the case number starting from 1, and Y is “Yes” if you can construct successfully or “No” if it’s impossible to reach the requirements.

If Y is “Yes”, output an integer M in a line, indicating the number of roads. Then M lines follow, each line contains two integers u and v (1 <= u, v <= N), separated with one single space, indicating a road direct from town u to town v. If there are multiple possible solutions, print any of them.

Sample Input

3
3
2 1 0
2
1 1
4
3 1 1 0

Sample Output

Case #1: Yes
2
1 2
2 3
Case #2: No
Case #3: Yes
4
1 2
1 3
2 4
3 4

Author

SYSU

给你每个点所能到达的其他点个数(有向图),然后让你判断是否存在合法的图,不能形成环和自环。开始的时候感觉没有思路,后来按照点的个数从小到大处理,然后发现如果每次从最小的开始连边,那么对于一个点,他的后继肯定就已经有了贡献,那么他的贡献就是1,那么问题就变为了,将点的格苏从小到大排序,每次判断需要的点是不是小于等于已经处理的点的数量,然后从前向后取出对应的点就可。

#include <bits/stdc++.h>

using namespace std;

vector<int>E[1100];

typedef struct node
{
    int num,Id;

    bool operator < (const node &a)const
    {
        return num<a.num;
    }
}No;

No a[1100];

int main()
{
    int T;

    scanf("%d",&T);

    for(int z = 1;z<=T;z++)
    {
        int n;

        scanf("%d",&n);

        for(int i =1;i<=n;i++)
        {
            scanf("%d",&a[i].num);

            a[i].Id = i;
        }

        sort(a+1,a+n+1);

        bool flag = false;

        for(int i = 1;i<=n;i++) E[i].clear();

        int ans = 0;

        for(int i = 1;i<=n;i++)
        {
            if(a[i].num>=i) {
                flag = true;
                break;
            }

            for(int j = 1;j<=a[i].num;j++)
            {
                ans++;
                E[a[i].Id].push_back(a[j].Id);
            }
        }
        printf("Case #%d: ",z);
        if(flag) printf("No\n");
        else {
            printf("Yes\n");

            printf("%d\n",ans);

            for(int i =1;i<=n;i++)
            {
                for(int j =0;j<E[i].size();j++)
                {
                    printf("%d %d\n",i,E[i][j]);
                }

            }
        }

    }
    return 0;
}

HDU【5816】——Hearthstone

Time Limit: 2000/1000 MS (Java/Others)Memory Limit: 65536/65536 K (Java/Others)
Problem Description

Hearthstone is an online collectible card game from Blizzard Entertainment. Strategies and luck are the most important factors in this game. When you suffer a desperate situation and your only hope depends on the top of the card deck, and you draw the only card to solve this dilemma. We call this “Shen Chou Gou” in Chinese.
这里写图片描述
Now you are asked to calculate the probability to become a “Shen Chou Gou” to kill your enemy in this turn. To simplify this problem, we assume that there are only two kinds of cards, and you don’t need to consider the cost of the cards.
-A-Card: If the card deck contains less than two cards, draw all the cards from the card deck; otherwise, draw two cards from the top of the card deck.
-B-Card: Deal X damage to your enemy.
这里写图片描述
Note that different B-Cards may have different X values.
At the beginning, you have no cards in your hands. Your enemy has P Hit Points (HP). The card deck has N A-Cards and M B-Cards. The card deck has been shuffled randomly. At the beginning of your turn, you draw a card from the top of the card deck. You can use all the cards in your hands until you run out of it. Your task is to calculate the probability that you can win in this turn, i.e., can deal at least P damage to your enemy.

Input

The first line is the number of test cases T (T<=10).
Then come three positive integers P (P<=1000), N and M (N+M<=20), representing the enemy’s HP, the number of A-Cards and the number of B-Cards in the card deck, respectively. Next line come M integers representing X (0

Output

For each test case, output the probability as a reduced fraction (i.e., the greatest common divisor of the numerator and denominator is 1). If the answer is zero (one), you should output 0/1 (1/1) instead.

Sample Input

2
3 1 2
1 2
3 5 10
1 1 1 1 1 1 1 1 1 1

Sample Output

1/3
46/273

Author

SYSU

给你两种牌,一种牌是可以再抽两张,一种是伤害,问可以打死对方的概率是多少。由于牌的总数只有20个,所以可以状压一下,当当前的状态可以杀死对方的时候,剩下的就是全排列

#include <bits/stdc++.h>

using namespace std;

typedef long long LL;

const int Max = 1<<21;

LL fac[30];

LL dp[Max];

int p[30];

int T;

int n,m,ph;

int num1 ,num2;

bool ok(int s)
{
    num1 = 0,num2 = 0;

    for(int i = 0;i<m;i++) if(s&(1<<i)) num1++;

    for(int i = 0;i<n;i++) if(s&(1<<(i+m))) num2++;

    return num2-num1+1>=0;

}


int count(int s)
{
    int ans =0 ;

    for(int i =0;i<m;i++) if(s&(1<<i)) ans+=p[i];

    return ans;
}
void Init()
{
    fac[0] =1;

    for(int i = 1;i<=21;i++) fac[i]=fac[i-1]*i;
}

int main()
{
    scanf("%d",&T);

    Init();

    while(T--)
    {
        scanf("%d %d %d",&ph,&n,&m);

        for(int i =0;i<m;i++) scanf("%d",&p[i]);

        memset(dp,0,sizeof(dp));

        dp[0] = 1;

        LL sum = 0;

        for(int i =0;i<(1<<(n+m));i++)
        {
            if(!dp[i] || !ok(i)) continue;

            int ans = count(i);

            if(ans>=ph)
            {
                sum+=dp[i]*fac[n+m-num1-num2];

                continue;
            }

            if(num2-num1+1==0)continue;

            for(int j = 0;j<n+m;j++)
            {
                if(i&(1<<j)) continue;

                dp[i^(1<<j)]+=dp[i];
            }
        }

        LL g = __gcd(sum,fac[n+m]);

        printf("%lld/%lld\n",sum/g,fac[n+m]/g);

    }
    return 0;
}

HDU【5818】——Joint Stacks

Time Limit: 8000/4000 MS (Java/Others)Memory Limit: 65536/65536 K (Java/Others)
Problem Description

A stack is a data structure in which all insertions and deletions of entries are made at one end, called the “top” of the stack. The last entry which is inserted is the first one that will be removed. In another word, the operations perform in a Last-In-First-Out (LIFO) manner.
A mergeable stack is a stack with “merge” operation. There are three kinds of operation as follows:

  • push A x: insert x into stack A
  • pop A: remove the top element of stack A
  • merge A B: merge stack A and B

After an operation “merge A B”, stack A will obtain all elements that A and B contained before, and B will become empty. The elements in the new stack are rearranged according to the time when they were pushed, just like repeating their “push” operations in one stack. See the sample input/output for further explanation.
Given two mergeable stacks A and B, implement operations mentioned above.

Input

There are multiple test cases. For each case, the first line contains an integer N(0 < N≤105), indicating the number of operations. The next N lines, each contain an instruction “push”, “pop” or “merge”. The elements of stacks are 32-bit integers. Both A and B are empty initially, and it is guaranteed that “pop” operation would not be performed to an empty stack. N = 0 indicates the end of input.

Output

For each case, print a line “Case #t:”, where t is the case number (starting from 1). For each “pop” operation, output the element that is popped, in a single line.

Sample Input

4
push A 1
push A 2
pop A
pop A
9
push A 0
push A 1
push B 3
pop A
push A 2
merge A B
pop A
pop A
pop A
9
push A 0
push A 1
push B 3
pop A
push A 2
merge B A
pop B
pop B
pop B
0

Sample Output

Case #1:
2
1
Case #2:
1
2
3
0
Case #3:
1
2
3
0

Author

SYSU

模拟题,就不解释了。

#include <bits/stdc++.h>

using namespace std;

typedef struct node
{
    int num,t;

    node(){}

    node(int _num,int _t):num(_num),t(_t){}

    bool operator < (const node &a)const
    {
        return t<a.t;
    }
}No;


char s[2],op[10];

char s1[2],s2[2];

int data;

int main()
{
    //freopen("in.in","r",stdin);
    int n;

    int z = 1;

    while(~scanf("%d",&n)&&n){

        priority_queue<No>Q;

        priority_queue<No>Q1;

        priority_queue<No>Q2;

        printf("Case #%d:\n",z++);

        for(int i = 1;i<=n;i++)
        {
            scanf("%s",op);

            if(op[1] == 'u')
            {
                scanf("%s %d",s,&data);

                if(s[0] == 'A') Q1.push(node(data,i));

                else Q2.push(node(data,i));
            }
            else if(op[1] == 'o')
            {
                scanf("%s",s);

                if(s[0] == 'A')
                {
                    if(Q1.empty()) printf("%d\n",Q.top().num),Q.pop();

                    else printf("%d\n",Q1.top().num),Q1.pop();
                }
                else 
                {
                    if(Q2.empty()) printf("%d\n",Q.top().num),Q.pop();

                    else printf("%d\n",Q2.top().num),Q2.pop();
                }
            }
            else
            {
                scanf("%s %s",s1,s2);
                while(!Q2.empty()) Q.push(Q2.top()),Q2.pop();
                while(!Q1.empty()) Q.push(Q1.top()),Q1.pop();
            }
        }    
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值