第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明),签到题3题

Posted 小哈里

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明),签到题3题相关的知识,希望对你有一定的参考价值。

文章目录

补题链接:https://ac.nowcoder.com/acm/contest/32708

K.King of Gamers

链接:https://ac.nowcoder.com/acm/contest/32708/K
来源:牛客网

题目描述
Little G is going to play nn games.

Little G is the king of gamers. If he wants to win, he will definitely win a game. But if he doesn’t care about winning or losing, he will lose a game because of his bad luck. Little G has an expected winning rate of x=\\fracabx=
b
a

. When playing the ii-th game, if his current winning rate is lower than or equal to xx, he will be eager to win and win the game easily. Otherwise, he will enjoy the game and lose it.

Given n,a,bn,a,b, Little G is wondering how many games he will win.
Note that when playing the first game, the winning rate is regarded as 00.

It is guaranteed that the answer is either \\lfloor nx \\rfloor⌊n∗x⌋ or \\lfloor nx \\rfloor +1⌊n∗x⌋+1.
输入描述:
The input consists of multiple test cases.

The first line consists of a single integer TT (1\\le T \\le 1000001≤T≤100000) - the number of test cases.

In the following TT lines, each line consists of three integers n,a,bn,a,b (1\\le n\\le 10^9, 0\\le a\\le b\\le 10^9,b\\neq 01≤n≤10
9
,0≤a≤b≤10
9
,b


=0), denoting a test case.

输出描述:
Print TT lines. Print one integer in each line, representing the answer of a test case.
示例1
输入
复制
3
4 3 5
8 7 10
1 1 3
输出
复制
2
5
1
备注:
In the first test case, x=\\frac35=0.6x=
5
3

=0.6:
When playing the first game, the winning rate = 0\\le x0≤x, so Little G will win the game;
When playing the second game, the winning rate = \\frac11 > x
1
1

x, so Little G will lose the game;
When playing the third game, the winning rate = \\frac12 \\le x
2
1

≤x, so Little G will win the game;
When playing the fourth game, the winning rate = \\frac23 > x
3
2

x, so Little G will lose the game.
In total, Little G will win 22 games, which is the answer of the first test case.

题意:

  • 小G在玩n场游戏,在一场游戏中小G想赢的话就一定会赢,并且在小G心中有一个胜率 x = a/b,当前胜率低于 x 时,一定会赢,高于 x 时,一定会输。
  • T组(1e5)数据,每次给出n, a, b(1e9)。问小G会赢多少场。

思路:

  • 第1场时,小G胜率为0,所以第1场必胜。
    此后n-1场,盲猜再让小G再赢(n-1)(a/b)场,那么加上第一场就刚好是胜率大于x的最小的胜率。
  • 对于这种出入输出确定的结论题,如果推不出式子的话。
    可以直接打表, 不难发现规律。
  • 参考证明:

    https://zhuanlan.zhihu.com/p/501424566

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e6+10;

void solve()
    LL n, a, b;  cin>>n>>a>>b;
    cout<<((n-1)*a/b+1)<<"\\n";


int main()
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T=1;  cin>>T;
    while(T--)
        solve();
    
    return 0;

D.Divisions

链接:https://ac.nowcoder.com/acm/contest/32708/D
来源:牛客网

题目描述
Nami will get a sequence SS of nn positive integers S_1, S_2, \\dots, S_nS
1

,S
2

,…,S
n

soon and she wants to divide it into two subsequences.

At first, Nami has two empty sequences S_AS
A

and S_BS
B

. She will consider each integer in SS in order, and append it to either S_AS
A

or S_BS
B

. Nami calls sequences S_A, S_BS
A

,S
B

she gets in the end a division of SS. Note that S_AS
A

and S_BS
B

are different and subsequences can be empty, so there are 2^n2
n
ways to divide SS into S_AS
A

and S_BS
B

, which means there are 2^n2
n
possible divisions of SS.

For a division, supposing that there are n_An
A

integers in S_AS
A

and n_Bn
B

integers in S_BS
B

, Nami will call it a great division if and only if the following conditions hold:

S_A,1\\leq S_A,2\\leq \\dots\\leq S_A,n_AS
A,1

≤S
A,2

≤⋯≤S
A,n
A

S_B,1\\geq S_B,2\\geq \\dots\\geq S_B,n_BS
B,1

≥S
B,2

≥⋯≥S
B,n
B

Nami defines the greatness of SS as the number of different great divisions of SS. Now Nami gives you a magic number kk, and your task is to find a sequence SS with the greatness equal to kk for her.

Note that the length of SS should not exceed 365365 and the positive integers in SS should not exceed 10^810
8
.

If there are several possible sequences, you can print any of them. If there is no sequence with the greatness equal to kk, print -1−1.

输入描述:
A single line contains an integer kk (0\\leq k\\leq 10^80≤k≤10
8
) - the magic number from Nami.
输出描述:
If there is no sequence with the greatness equal to kk, print -1−1 in a single line.

Otherwise, in the first line, print the length nn (1\\leq n\\leq 3651≤n≤365) of the sequence SS.

In the second line, print nn positive integers S_1, S_2, \\dots, S_nS
1

,S
2

,…,S
n

(1\\leq S_i\\leq 10^81≤S
i

≤10
8
) - the sequence for Nami.

示例1
输入
复制
1
输出
复制
6
1 1 4 5 1 4
说明
For the sequence S = 1,1,4,5,1,4S=1,1,4,5,1,4, it can be shown that the only great division of SS is:

S_A = 1,1,4,4S
A

=1,1,4,4, S_B = 5,1S
B

=5,1
示例2
输入
复制
2
输出
复制
1
1
说明
For the sequence S = 1S=1, it can be shown that all the divisions of SS are great:

S_A = 1S
A

=1, S_BS
B

is empty;

S_AS
A

is empty, S_B = 1S
B

=1.

题意:

  • 有 n 个顺序不定的玻璃球,第 i 个玻璃球有p[i]的概率被移动到最前面,每一次移动的代价是该球前面的玻璃球的数量。
  • 问移动无穷次时,期望代价为多少?

思路:

  • 任意选择一对玻璃球(这两球在无限次中,一定会相邻),此时将j移动到i前面的代价为1,他们被选中的概率分别是pi和pj。
  • 此时将j移动到i前, 会对最终的期望代价产生大小为 p i ∗ p j p i + p j \\fracpi*pjpi+pj pi+pjpipj的贡献。
  • 最后对所有(i,j)对的贡献求和即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e6+10;
double p[N];

void solve()
    int n;  cin>>n;
    for(int i = 1; i <= n; i++)cin>>p[i];
    double res = 0;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n; j++)
            if(i != j)res += p[i]*p[j]/(p[i]+p[j]);
        
    
    printf("%.10lf\\n", res);


int main()
    // ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T=1;  //cin>>T;
    while(T--)
        solve();
    
    return 0;

F.Find the Maximum

链接:https://ac.nowcoder.com/acm/contest/32708/F
来源:牛客网

题目描述
A tree with nn vertices is a connected undirected graph with nn vertices and n-1n−1 edges.

You are given a tree with nn vertices. Each vertex has a value b_ib
i

. Note that for any two vertices there is exactly one single path between them, whereas a simple path doesn’t contain any edge more than once. The length of a simple path is considered as the number of edges in it.

You need to pick up a simple path whose length is not smaller than 11 and select a real number xx. Let VV be the set of vertices in the simple path. You need to calculate the maximum of \\frac\\sum_u\\in V(-x^2+b_ux)|V|
∣V∣

u∈V

(−x
2
+b
u

x)

.

输入描述:
The first line contains a single integer nn (2\\le n \\le 10^52≤n≤10
5
), indicating the number of vertices in the tree.

The second line contains nn integers b_1,b_2,\\cdots,b_nb
1

,b
2

,⋯,b
n

(-10^5\\le b_i \\le 10^5−10
5
≤b
i

≤10
5
), indicating the values of each vertex.

Each line in the next n-1n−1 lines contains two integers u,vu,v, indicating an edge in the tree.

输出描述:
The output contains a single real number, indicating the answer.

Your answer will be accepted if and only if the absolute error between your answer and the correct answer is not greater than 10^-410
−4
.

示例1
输入
复制
2
3 2
1 2
输出
复制
1.562500

题意:

  • 要求构造一个序列,可以将序列切割成两部分,
    SA,1​≤SA,2​≤⋯≤SA,nA​​, 即S的非递减子序列(位置不要求连续)
    SB,1≥SB,2≥⋯≥SB,nB, 即S的非递增子序列(SA和SB不能相同,可以为空)
    显然,存在多种方式能够将序列S序列分割。
  • 现在给出K(1e8),要求构造一个长度<365的序列S,满足恰好有K种方式能将序列S进行分割。(S中的元素<1e8)

思路:

  • 发现结论1:若没有n的长度限制,只需要对于任意的K,构造长度为K-1的完全递减或递增序列即可。(去掉任意一个元素,或者不去掉,或者都去掉) 123456
  • 发现结论2:若K = 2^n,则只需要构建一个长度为n的,元素全部相等的序列即可。(二进制每个元素选或不选的方案数)1111111
  • 我们可以构造的是一种类似于“111222233334444”这样的序列
    我们构造一个完全上升(或者完全下降)的序列,这样每次我们只取一位或者几位相同的序列,然后其他的序列保证是上升。
    这样我们就可以在每一位相等的1111,2222,3333中,用类似于 2 i 1 + 2 i 2 + 2 i 3 . . . . 2 i k 2^i_1+2^i_2+2^i_3....2^i_k 2i1+2i2+2i3....2ik的形式构造出任何种类数的序列,自然也能表示出恰好为K种的情况。
  • 最后k=0或1的时候需要特判掉。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e6+10;

void solve()
    int k;  cin>>k;
    if(k==0) cout<<"6\\n"<<"3 2 4 1 2 3\\n"; return ;
    if(k==1) cout<<"6\\n"<<"1 1 4 5 1 4\\n"; return ;
    k--;  //空集
    vector<int>res;
    int num = 0;
    for(int i = 30; i >= 1; i--)
        int x = (1<<i)-1;  //表示的方案数
        while(k >= x)
            k -= x;
            ++num;
            for(int j = 1; j <= i; j++)res.push_back(num);
        
    
    cout<<res.size()<<"\\n";
    for(int i = 0; i < res.size(); i++)
        cout<<res[i]<<" \\n"[i==res.size()-1];
    


int main()
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T=1;  //cin>>T;
    while(T--)
        solve();
    
    return 0;


以上是关于第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明),签到题3题的主要内容,如果未能解决你的问题,请参考以下文章

第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海),签到题6题

第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海),签到题6题

第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京),签到题5题

第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(南京),签到题5题

第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(沈阳),签到题5题

第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(沈阳),签到题5题