【清北学堂2018-刷题冲刺】Contest 2
这场比赛的T1相当智熄。由于至今无法理解题意,我只能解出前20分。诸位dalao谁能比较好地理解题意(独立性)的,请联系我,不胜感激。
在此本蒟蒻只能贴上题面:
Task 1:选举
【问题描述】
一场选举有三位选手分别编号为1,2,3,还有两位评委4,5。
评委打分时会给出一个{1,2,3}的排列,表示评委对选手的喜爱程度。例如评委给出一个排列{2,1,3},表示最喜欢2,其次是1,最后是3。
两位评委将分别给出排列x、y。你需要做的是综合考虑x、y,给出一个最终的排名z。
由于事先不知道x、y,所以你需要对于每一种不同的x、y,都提前设计好相应的z。(显然x、y有36种情况)
正式地,你需要设计一个映射{X,Y}-->{Z},其中定义域是评委的排列,值域是你给出的最终排列。(定义域大小是36,值域大小是6,所以映射数量是6^36)。为了方便,用z=f(x,y)表示评委打分是x,y时最终排名是z。
如果随便给一个映射,可能会被喷,比如两个评委都最喜欢1,你最后却把1排在最后。为了避免这种情况,你的映射可能需要满足几个条件:
一致性:对于选手a,b,如果两个评委都更喜欢a,那么最终排名中a应当排在b前面。
独立性:定义函数I(x,a,b),如果排列x中a的位置比b靠前,那么I(x,a,b)=1.否则I(x,a,b)=0。对于选手a,b,考虑评委打分的两种情况(x1,y1)和(x2,y2),如果I(x1,a,b)=I(x2,a,b),并且I(y1,a,b)=I(y2,a,b),那么f(x1,y1)和f(x2,y2)应当满足I(f(x1,y1),a,b)=I(f(x2,y2),a,b)。
非独裁:如果对于任意的排列x,y,f(x,y)=x,那么称评委4独裁。如果对于任意的x,y,f(x,y)=y,那么称评委5独裁。非独裁就是两个评委都不独裁。
【输入格式】
一个数m
【输出格式】
一行一个数
如果m=1,输出共有多少种映射方案(正如题目中所说,方案数是6^36)。
如果m=2,输出有多少方案满足一致性。
如果m=3,输出有多少方案满足独立性。
如果m=4,输出有多少方案满足一致性、独立性。
如果m=5,输出有多少方案满足一致性、独立性、非独裁。
【样例输入】
1
【样例输出】
10314424798490535546171949056
【数据规模和约定】
五个点,一个点20分。
Task 2:游戏
【问题描述】
Alice和Bob在玩一个游戏。最初Alice有n颗宝石,Bob有m颗宝石。每一回合,他们会扔一枚硬币,硬币有p的概率正面朝上。
如果正面朝上,Alice需要给Bob一颗宝石(如果Alice没有宝石了,就不用给了)。否则Bob需要给Alice一颗宝石(如果Bob没有宝石了,就不用给了)。
如果某个回合结束时,Alice有n颗宝石,那么游戏结束。
求游戏期望进行多少回合。
【输入格式】
第一行两个正整数n,m
第二行一个有限小数p(小数不超过6位)
【输出格式】
一个实数表示答案。
如果与标准输出的相对误差不超过1e-6就能得分
【样例输入】
1 1
0.5
【样例输出】
3.00000000
【数据规模和约定】
- 对于30%的数据, n,m<=1
- 对于60%的数据, n,m<=10
- 对于100%的数据, n,m<=100
我最初的想法是按照回合DP,感觉精度上问题应该不大,赛后经过dummy给的大样例提醒才意识到这样做精度会出现非常大的问题。因为对于很多情况下来讲,期望次数可以非常大,举个例子:对于某组数据,前200000步只占了40%的期望,而剩下60%的期望虽然极其分散,但是其每个值都在200000以上,答案误差可想而知。
faebdc大佬给出的题解最初让我十分困惑,(dalao的方法太过高级而本蒟蒻脑子又不够)直到今天下午我才得以基本理解这种方法。思路是这样的:
考虑让进行的回合数趋于无限轮,那么落到每一个点上的期望都会趋于一个固定的值 。
对于两个相邻点:i和i+1来说,i到i+1的期望是p,i+1到i的期望是1-p,那么二者最终具有的期望比是1-p:p。
这样我们就可以从0开始递推,到n+m为止,求出从起点走无限轮后,也就是趋于稳态时,到达每一个点的期望。其中可以设0点为单位1,最终再把每个点的值除以总值得到真正的期望。
想象把走的每一步展开成链,每次都到达一个不同的点,到达终点的期望就是p[n],那么期望步数也就是1/p[n]了。
时间复杂度O(n),100的范围咋跑都能过。
当然啦,还有另外一种更容易理解的方法:根据关系构造n元1次方程组,利用高斯消元解方程。但是由于这种方法码量大,速度慢,加上我特别的懒,所以这里就不写了,时间复杂度O(n^3)。
Code:
//game 100pts
#include<cstdio>
using namespace std;
int n,m;
long double p,sum=1.0,val[105];
int main(){
freopen("game.in","r",stdin);
freopen("game.out","w",stdout);
scanf("%d%d%Lf",&n,&m,&p);
val[0]=1.0;
long double v=(1-p)/p;
for(int i=1;i<=n+m;i++){
val[i]=val[i-1]*v;
sum+=val[i];
}//get expected percentage after infinity rounds
for(int i=0;i<=n+m;++i){
val[i]/=sum;
}
printf("%.10Lf\n",1/val[n]);
return 0;
}
——————————————————————————————
Task 3:网络
【问题描述】
在计算机科学中,经常要通过分析变量之间的相关性来简化计算过程。变量间的相关性可以用有向图G=(V,E)来表示,图中的点表示变量,边表示变量间的关系。这里G满足:G中的所有边都从编号小的点指向编号大的点。
从图中选出一个点集T⊆V,如果T中的任意两个点之间都有边(方向是编号小的点指向编号大的点),则称T为团。特别地,空集也认为是一个团。
如果存在一个点,与T中的任意一个点之间都有边(方向是编号小的点指向编号大的点),那么称T为可扩团。
如果一个团S不是可扩团,那么称它为极大团。
给出G,求G有多少个不同的极大团。
这里G满足一个性质:对于G中任意一个点i,用H[i]表示编号比i小的点中所有与i有边相连的点的集合,那么H[i]是一个团。
【输入格式】
第一行n,m,表示点数和边数
接下来m行,每行两个数a,b,表示有从a到b的边
注意可能有重边
保证输入的图满足问题描述中提到的性质。
【输出格式】
极大团数量
【样例输入】
4 5
1 2
1 3
2 3
2 4
3 4
【样例输出】
2
【数据规模和约定】
- 对于30%的数据, n<=10
- 对于60%的数据, n<=1000
- 对于100%的数据, n,m<=1000000
这个题目更像是一个结论题。首先你肯定可以得到这样一个简单的推论:
- 对于每个点i,H[i]是团,那么H[i]+i也一定是团。
- 所以,极大团一定出自于H[i]+i中。
接下来问题就在于如何判断H[i]是否为极大团。
最直观的想法是直接判断。从大的点到小的点遍历,分别遍历它们所属的团并确定其是否为极大团,统计最终答案,时间复杂度O(n2),空间复杂度O(n2),60%的数据绰绰有余。
但是对于100%的数据,n<=1000000,就比较麻烦了。
首先,我们需要用链式前向星存图,这就决定了对边的判重要慎重进行,还有就是要处理边的先后顺序,需要一次O(nlogn)的排序,数据范围n是1000000,排序这种做法本身已经有些冒险,那么在输入和循环上就需要稍微卡一点常数保证程序不被卡掉。
既然数据范围升到了1000000,那么O(n^2)的写法显然不行。经过慎重思考,可以得到这样一个结论:
- 对于一个团i+H[i],如果它不是极大团,那么一定存在一个点j满足size(H[j])=size(1+H[i]),且i为j团中的最大点。
根据题目中给出的性质(H[i]一定是团),我们可以知道:只要size(H[j])=size(1+H[i]),而且团j中最大点为i,那么整个团i都会被j包括在内。
结论考场上不好想,想出来也不好证,所以这个题目就告诉我们两个道理:
- 暴力大法好
- 大胆猜想,胡乱证明
经过上面结论的优化,我们就得到了一份O(n+logn)的代码。注意卡常防止TLE,不要像标程一样丑到1000ms。
Code:
#include<cstdio>
#include<iostream>
#include<algorithm>
#define MAXN 1000010
using namespace std;
bool vis[MAXN];
int n,m,sz[MAXN],low[MAXN];
inline int max(int x,int y){
return x>y?x:y;
}
struct edge{
int u,v;
bool operator<(const edge &rhs)const{
return u==rhs.u?v<rhs.v:u<rhs.u;
}
}e[MAXN];
inline int read(){
int s=0,w=1;
char ch=getchar();
while('9'<ch||ch<'0'){
if(ch=='-')w=-1;
ch=getchar();
}
while('0'<=ch&&ch<='9'){
s=s*10+ch-'0';
ch=getchar();
}
return s*w;
}
int main(){
freopen("network.in","r",stdin);
freopen("network.out","w",stdout);
n=read(),m=read();
for(register int i=1;i<=m;++i){
e[i].u=read();
e[i].v=read();
}
sort(e+1,e+1+m);
int cnt=0;
for(register int i=1;i<=m;++i){
e[++cnt]=e[i];
while(e[i].u==e[i+1].u&&e[i].v==e[i+1].v){
++i;
}
}
for(register int i=1;i<=cnt;++i){
sz[e[i].v]++;
low[e[i].v]=max(low[e[i].v],e[i].u);
}
for(register int i=n;i>=1;--i){
if(sz[low[i]]<=sz[i]-1){
vis[low[i]]=true;
}
}
int ans=0;
for(register int i=1;i<=n;++i){
ans+=!vis[i];
}
printf("%d",ans);
return 0;
}
【清北学堂2018-刷题冲刺】Contest 2的更多相关文章
- 2017 清北济南考前刷题Day 7 afternoon
期望得分:100+100+30=230 实际得分:100+100+30=230 1. 三向城 题目描述 三向城是一个巨大的城市,之所以叫这个名字,是因为城市中遍布着数不尽的三岔路口.(来自取名力为0的 ...
- 2017 清北济南考前刷题Day 1 afternoon
期望得分:80+30+70=180 实际得分:10+30+70=110 T1 水题(water) Time Limit:1000ms Memory Limit:128MB 题目描述 LYK出了道水 ...
- 2017 清北济南考前刷题Day 3 morning
实际得分:100+0+0=100 T1 右上角是必败态,然后推下去 发现同行全是必胜态或全是必败态,不同行必胜必败交叉 列同行 所以n,m 只要有一个是偶数,先手必胜 #include<cstd ...
- 2017 清北济南考前刷题Day 3 afternoon
期望得分:100+40+100=240 实际得分:100+40+100=240 将每个联通块的贡献乘起来就是答案 如果一个联通块的边数>点数 ,那么无解 如果边数=点数,那么贡献是 2 如果边数 ...
- 2017 清北济南考前刷题Day 4 afternoon
期望得分:30+50+30=110 实际得分:40+0+0=40 并查集合并再次写炸... 模拟更相减损术的过程 更相减损术,差一定比被减数小,当被减数=减数时,停止 对于同一个减数来说,会被减 第1 ...
- 2017 清北济南考前刷题Day 7 morning
期望得分:100+50+20=170 实际得分:10+50+20=80 1. 纸牌 题目描述 在桌面上放着n张纸牌,每张纸牌有两面,每面都写着一个非负整数.你的邪王真眼可以看到所有牌朝上的一面和朝下的 ...
- 2017 清北济南考前刷题Day 6 afternoon
期望得分:100+100+30=230 实际得分: 正解: 枚举最高的位,这一位m是1但实际用了0 然后剩余的低位肯定是 正数就用1,负数用0 考场思路:数位DP #include<cstdio ...
- 2017 清北济南考前刷题Day 6 morning
T1 贪心 10 元先找5元 20元 先找10+5,再找3张5 #include<cstdio> using namespace std; int m5,m10,m20; int main ...
- 2017 清北济南考前刷题Day 5 afternoon
期望得分:100+100+30=230 实际得分:0+0+0=30 T1 直接模拟 #include<cstdio> #include<iostream> using name ...
- 2017 清北济南考前刷题Day 5 morning
期望得分:100+100+0=200 实际得分: 坐标的每一位不是0就是1,所以答案就是 C(n,k) #include<cstdio> #include<iostream> ...
随机推荐
- epoch、 iteration和batchsize区别
转自: https://blog.csdn.net/qq_27923041/article/details/74927398 深度学习中经常看到epoch. iteration和batchsize,下 ...
- linux 安装python 和pip
下载文件 python官网:https://www.python.org/downloads/ 百度网盘http://pan.baidu.com/s/1mixGB12 密码 9nzu [r ...
- mysql必须知道的
https://blog.csdn.net/xlgen157387/article/details/73691848
- Nginx TSL/SSL优化握手性能
L:131
- Linux系统下手把手完成无人值守安装服务
刚入职的运维新手经常会被要求去做一些安装操作系统的工作,如果按照用镜像光盘安装操作系统,效率会相当低下.那么如何提升效率,搭建出一套可以批量安装Linux系统的无人值守的安装系统? PXE+TFTP+ ...
- BZOJ4321queue2——DP/递推
题目描述 n 个沙茶,被编号 1~n.排完队之后,每个沙茶希望,自己的相邻的两 人只要无一个人的编号和自己的编号相差为 1(+1 或-1)就行: 现在想知道,存在多少方案满足沙茶们如此不苛刻的条件. ...
- Codeforces 888G(分治+trie)
按位贪心,以当前考虑位是0还是1将数分成两部分,则MST中这两部分之间只会存在一条边,因为一旦有两条或以上的边,考虑两条边在原图中所成的环,显然这两条边有一条是环上的权值最大边,不会出现在MST中.则 ...
- 第三十四天 UDP协议 并发编程
一.今日内容 1.UDP协议 2.并发编程 操作系统的发展史 多道技术 进程 线程 IO模型 socketserver 案例:文件上传下载 元类 单例 logging filter 二.TCP半连接池 ...
- POJ3013-Big Christmas Tree-最短路
题意:给出一个图,每个节点都有权值,每条边也有费用.要求建立一颗树,使总花费最小.树上每连一条边的花费定义为孩子节点权值和×此边费用. 做法:分析可知,最终的答案为所有节点的权值×到根节点的距离.可以 ...
- 【XSY2730】Ball 多项式exp 多项式ln 多项式开根 常系数线性递推 DP
题目大意 一行有\(n\)个球,现在将这些球分成\(k\) 组,每组可以有一个球或相邻两个球.一个球只能在至多一个组中(可以不在任何组中).求对于\(1\leq k\leq m\)的所有\(k\)分别 ...