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

简介: 第 46 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(济南),签到题2题

@[toc]

补题链接:https://pintia.cn/market/item/1459833348620926976

K.Search For Mafuyu

K
Search For Mafuyu
(300分)
Mafuyu has hidden in Sekai, and Kanade is searching for her.

In Sekai, there is nothing but a lot of rooms. There are n rooms in Sekai, numbered from 1 to n. Besides, n−1 pairs of rooms are directly connected by corridors, such that it is possible to move from one room to any other one, using one or more corridors. In other words, rooms in Sekai form a tree.

Kanade is at room 1, and she knows that Mafuyu may hide in any room except room 1, with uniform probability. In one second, Kanade can move to a room adjacent to the room she is currently in. Once Kanade is in the same room with Mafuyu, she immediately finds her. What is the minimum expected time for Kanade to find Mafuyu, if Kanade is taking the optimal strategy?

Input
The first line contains an integer t (1≤t≤1000) --- the number of test cases.

The first line in each test case contains an integer n (2≤n≤100) --- the number of rooms.

Each of the following n−1 lines contains two integers a
i

, b
i

(1≤a
i

,b
i

≤n) --- the rooms connected by the i-th corridor. It is guaranteed that it is possible to move from one room to any other one, using one or more corridors.

Output
Output t real numbers. For each test case, output the minimum expected time. Your answer is considered correct if the absolute or relative error is less than 10
−9
.

Sample Input
4
2
1 2
5
1 2
2 3
3 4
1 5
7
1 2
1 3
2 4
2 5
3 6
3 7
10
1 2
2 3
3 4
1 5
5 6
6 7
1 8
8 9
9 10
Output
1.0000000000
3.2500000000
5.3333333333
8.0000000000

题意:

  • T组数据(1000),每次给出一个n个点(100)的树,A和B走迷宫,A在1号点,B藏在某个树中某个点。
  • 求A找到B的最短期望时间。

思路:

  • 最短期望时间,即最优查找策略肯定是先走大小小的子树,再依次走大小大的。所以先跑一遍dfs记录每个节点子树的大小。
  • 然后再跑一遍dfs,对于遇到的节点x,按照子树大小从小往大的走。开个变量维护当前走的步数tim,每次遇到一个点就累加到ans上去,最后除掉n-1即可。
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 550;

vector<int>G[maxn];
int siz[maxn];
void dfs(int x, int fa){
   
    siz[x] = 1;
    for(int to : G[x]){
   
        if(to!=fa){
   
            dfs(to,x);
            siz[x] += siz[to];
        }
    }
}

bool cmp(int x, int y){
   return siz[x]<siz[y]; }
int tim = 0, res = 0;
void dfs2(int x, int fa){
   
    res += tim;
    sort(G[x].begin(),G[x].end(),cmp);
    for(int to : G[x]){
   
        if(to!=fa){
   
            tim++;
            dfs2(to, x);
            tim++;
        }
    }
}

int main(){
   
    int T;  cin>>T;
    while(T--){
   
        memset(siz,0,sizeof(siz));
        int n;  cin>>n;
        for(int i = 0; i <= n; i++)G[i].clear();
        for(int i = 1; i < n; i++){
   
            int u, v;  cin>>u>>v;
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1,0);
        res = tim = 0;
        dfs2(1,0);
        printf("%.11lf\n", res*1.0/(n-1));
    }
    return 0;
}

C.Optimal Strategy

C
Optimal Strategy
(300分)
Ena and Mizuki are playing a game.

There are n items in front of them, numbered from 1 to n. The value of the i-th item is a
i

. Ena and Mizuki take turns to move, while Ena moves first. In a move, the player chooses an item that has not been taken and takes it away. The game ends when all items are taken away. The goal of either player is to maximize the sum of values of items they have taken away.

Given that both players move optimally, how many possible game processes are there? Since the number may be too large, you should output it modulo 998244353.

Two processes are considered different if there exists some integer i(1≤i≤n) such that the indices of items taken away in the i-th move are different.

Input
The first line contains an integer n (1≤n≤10
6
).

The second line contains n integers a
1

,a
2

,…,a
n

(1≤a
i

≤n).

Output
Output the answer.

Sample Input 1
3
1 2 2
Sample Output 1
4
Sample Input 2
6
1 3 2 2 3 1
Sample Output 2
120
Sample Input 3
12
1 1 4 5 1 4 1 9 1 9 8 10
Sample Output 3
28800
Explanations
In the first example, there are four possible processes:

[1,2,3].
[1,3,2].
[2,3,1].
[3,2,1].
Here [a,b,c] means that in the first move Ena takes away the a-th item, in the second move Mizuki takes away the b-th item, and in the final move Ena takes away the c-th item.

Note that [2,1,3] is not a possible process, since the second move is not optimal for Mizuki.

题意:

  • 给定n个物品,每个物品有一个价值。 Ena和Mizuki轮流取物品,每个人的得分是其所取物品的价值总和。
  • Ena先手,每个人取的都是当前的最优解,问结束时中间有多少种不同的取法。答案模998244353。
  • 如果存在一些整数相等,但是下标不同,算为两种方式。

思路:

  • 要让和最大,自然想到每个数都不能太小。若直接贪心每次双方都取最大第一个样例都解释不通。
    再模拟样例二发现暗示比较明显,每个数都出现偶数次,样例三便是奇偶出现次数都有。

  • 首先考虑当前最大值,如果是偶数个,那么会每次被两个两个的取;如果是奇数个,那么会被先手立刻取走一个,变成偶数的情况。
  • 开个桶数组维护每个数字的出现次数,第 i 个数出现 c[i] 次。
    对于奇数次的数,先手必然取走最大的一个数,后手取走次大的出现的奇数次的数,对结果不产生影响。
    对于偶数次的数,双方轮流从大到小拿,一方拿走一个另一方会立刻拿走相同的数,取当前数时有c[i]/2种方案。
  • 从小到大考虑每个数的出现次数,当前数的可选方案为c[i]/2。比当前数小的数的出现次数和sum可直接作为总和选取(因为是从小到大遍历,现在自己取了能取的最小值,之前的数是都不符合贪心策略的,因为它们都比最小值小,只有后面的数要符合贪心,因此前面的数在前面的过程中可以按照任意顺序取)
    大数一定可在小数之前被选,所以每个数的方案为C(c[i]/2+sum,c[i]/2),每个数内部排列方案数为 c[i]!。
  • 组合数需要预处理,不然会T。
  • 参考https://blog.csdn.net/m0_57050876/article/details/121356251

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const LL maxn = 1e6+10, mod = 998244353;

//预处理阶乘和逆元求组合数
LL fac[maxn], inv[maxn];
LL mpow(LL a, LL x) {
    if(x==0)return 1; LL t = mpow(a, x>>1); if(x%2==0)return t*t%mod; return t*t%mod*a%mod; }
LL init(LL _n){
   
    fac[0]=inv[0]=1;
    for(int i = 1; i < _n; i++){
   
        fac[i]=fac[i-1]*i%mod; inv[i]=mpow(fac[i],mod-2);
    }return 0;
}
LL C(LL x, LL y) {
   
    if(y<0 || y>x)return 0;
    return fac[x]*inv[y]%mod*inv[x-y]%mod;
}

LL c[maxn], mx, res = 1;

int main(){
   
    init(maxn-1);
    LL n;  cin>>n;  
    for(int i = 1; i <= n; i++){
   
        LL x;  cin>>x;  c[x]++;  mx = max(mx, x);
    }
    LL sum = 0;
    for(int i = 1; i <= mx; i++){
   
        if(c[i]==0)continue;
        LL up = floor(c[i]/2), down = up+sum;
        res = res*fac[c[i]]%mod*C(down, up)%mod;
        sum += c[i];
    }
    cout<<res%mod<<"\n";
    return 0;
}
目录
相关文章
|
存储 Go 容器
【golang】对键值有顺序要求时,不要使用 map
【golang】对键值有顺序要求时,不要使用 map
355 0
|
API
【工具推荐】 Obsidian 插件 Obsidian to Flomo 一键同步内容到 Flomo 插件
Obsidian to Flomo 是一款可以一键发送内容到 Flomo 的Obsidian 插件。
1538 0
|
机器学习/深度学习 算法 大数据
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
2024“华为杯”数学建模竞赛,对ABCDEF每个题进行详细的分析,涵盖风电场功率优化、WLAN网络吞吐量、磁性元件损耗建模、地理环境问题、高速公路应急车道启用和X射线脉冲星建模等多领域问题,解析了问题类型、专业和技能的需要。
5102 22
【BetterBench博士】2024 “华为杯”第二十一届中国研究生数学建模竞赛 选题分析
|
11月前
|
存储 人工智能 算法
《构建鸿蒙Next AI轻量化模型评估指标体系:解锁智能新境界》
在鸿蒙Next生态中,构建适合人工智能轻量化模型的评估指标体系至关重要。该体系涵盖准确性(识别和语义理解)、效率(响应时间和处理速度)、资源占用(CPU、内存、存储)、稳定性(崩溃率和容错能力)、可扩展性(模型更新和多设备适配)及安全性(数据隐私和算法公正)。各指标权重需根据应用场景调整,确保模型性能最优,提升用户体验。
343 2
|
分布式计算 DataWorks 搜索推荐
用户画像分析(MaxCompute简化版)
通过本教程,您可以了解如何使用DataWorks和MaxCompute产品组合进行数仓开发与分析,并通过案例体验DataWorks数据集成、数据开发和运维中心模块的相关能力。
|
SQL 关系型数据库 MySQL
Mysql学习笔记(三):fetchone(), fetchmany(), fetchall()详细总结
MySQL中用于数据检索的`fetchone()`, `fetchmany()`, `fetchall()`函数的功能、SQL语句示例和应用场景。
408 3
Mysql学习笔记(三):fetchone(), fetchmany(), fetchall()详细总结
|
Cloud Native Go API
Go语言在微服务架构中的创新应用与实践
本文深入探讨了Go语言在构建高效、可扩展的微服务架构中的应用。Go语言以其轻量级协程(goroutine)和强大的并发处理能力,成为微服务开发的首选语言之一。通过实际案例分析,本文展示了如何利用Go语言的特性优化微服务的设计与实现,提高系统的响应速度和稳定性。文章还讨论了Go语言在微服务生态中的角色,以及面临的挑战和未来发展趋势。
|
JavaScript iOS开发 MacOS
Jupyter模块Plotly及labextension插件的安装
Jupyter模块Plotly及labextension插件的安装
563 1
|
图计算 Python
【Leetcode刷题Python】42. 接雨水
使用栈的方法来解决LeetCode上的"接雨水"问题,通过计算柱子之间的凹槽来确定能接多少雨水,并给出了Python语言的实现代码。
203 0
|
机器学习/深度学习 人工智能 安全
精选CRM软件:顶级客户关系管理工具深度剖析
本文综合评测2024年顶级CRM工具,依据功能性、用户体验、集成能力、数据安全、客户支持及成本效益六大标准,深度剖析纷享销客、Salesforce、Microsoft Dynamics 365、用友CRM和SAP CRM等软件,为企业选型提供参考。