ACM暑假训练codeforces A. Arcade Game D. Frozen Rivers(康托展开式,spfa)
来源:互联网 发布:数据库基础知识总结 编辑:程序博客网 时间:2024/06/06 00:25
Arcade mall is a new modern mall. It has a new hammer game called "Arcade Game". In this game you're presented with a number nwhich is hanged on a wall on top of a long vertical tube, at the bottom of the tube there is a button that you should hit with your hammer.
When you hit the button with all your force (as you always do), a ball is pushed all over the tube and hit the number n. The number nflies in the air and it's digits fall back in any random permutation with uniform probability.
If the new number formed is less than or equal to the previous number, the game ends and you lose what ever the new number is. Otherwise (if the number is greater than the previous number), you are still in the game and you should hit the button again.
You win if the new number formed is greater than the previous number and it is equal to the greatest possible permutation number.
Can you compute the probability of winning?
The first line of the input contains the number of test cases T. Following that there are T lines represents T test cases. In each line, there is a single integer (1 ≤ n ≤ 109) the target number. The digits of n are all unique, which means that any 2 digits of n are different.
For each test case, print one line containing the answer. Print the answer rounded to exactly 9 decimal digits.
3952925592
0.0000000000.1666666670.194444444
In the first test case, the answer is 0 because 952 is greater than all 2,5 and 9 permutations so you can't win, whatever you do.
In the second test case, the answer is 0.166666667 because you may win by getting number 952 with probability 1/6.
In the third test case the answer is 0.194444444 because you may win by getting number 952 in round1 with probability 1/6 or you can win by getting number 925 in round 1 and then 952 in round 2 with probability 1/6 * 1/6.
【解析】:
题意,每变换一次全排列,胜利的方法是,递增的,并且最后一次必须是全排列最高项。
先用康托展开,算出输入的数字之后的全排列有多少种。
然后枚举。反正最后一项必选。
枚举选中间的一项、两项......
但是组合数C必须优化,才能保证不超时
【代码】:
#include <stdio.h>#include <iostream> #include <algorithm> using namespace std;typedef long long ll;ll fac[120];double C(ll n,ll m,ll A){//A除m+1次 double ans=1;for(int i=1;i<=m;i++){ans*=n;ans/=i;ans/=A;n--;}return ans/A;}int main(){int T;fac[0]=1;for(ll i=1;i<=110;i++){fac[i]=fac[i-1]*i;//阶乘 }cin>>T;while(T--){char n[22];cin>>n;ll c=strlen(n);for(int i=0;i<c;i++)a[i]=n[i]-'0';ll A=fac[c];//全排列;int b[16];memcpy(b,a,sizeof(a));sort(b,b+c);int dex[16]={0};for(int i=0;i<c;i++){dex[b[i]]=i;}int permu=0;int vis[16]={0};for(int i=0;i<c;i++){int cc=0;for(int j=0;j<a[i];j++)if(vis[j])cc++;permu+=(dex[a[i]]-cc)*fac[c-i-1];vis[a[i]]=1;}permu=fac[c]-permu-1;//以上康托展开,求得后面的全排列个数 double ans=0;double r=1.0/A;if(permu>0)ans+=r;double s=C(permu-1,1,A);if(1<=permu-1)ans+=s;for(int i=2;i<=permu-1;i++){//ans+=pow(r,i+1)*C(permu-1,i);s=s*(permu-i)/i/A;ans+=s;// *r^i+1}printf("%.9lf\n",ans);}return 0;}
In winter, all small rivers of Al-Asi great river in Syria are frozen. But when spring comes back they start to melt. These small rivers are connected to each other exactly like a tree, each river (direct edge in the tree) has a value equal to the amount of ice in it.
Here is the tree of the sample test case:
When rivers start to melt, water starts to flow from node 1 (root of the tree) to any node that it can reach. When the water first reaches a node u, ice starts to melt in all its direct children edges at a rate of 1 unit per second. Once (u, v) edge completely melted, the rate of melting of all other edges that start from u will slow down to be 0.5 unit per second, while the other edges that start from v start melting with 1 unit per second.
Given the rivers tree, and a certain time, can you tell us how many leaves of the tree did the water reach? A leaf is a node that has no children.
The first line contains T the number of test cases. For each test case, the first line contains N the number of nodes (2 ≤ N ≤ 100, 000). Followed by N - 1 lines, each line describes the nodes 2 to N. Each line will contain 2 integers Pi and Ci (1 ≤ Pi ≤ N) (0 ≤ Ci ≤ 100,000) representing the parent of the i-th node (i starts from 2 here) and the amount of ice in the edge connecting the current node to its parent. Node 1 is the root of the tree. After that there is a line contains (1 ≤ Q ≤ 100, 000), the number of queries. Then Q lines contain the times of these queries in seconds (0 ≤ query time ≤ 1012).
Print one line for each query in each test case, this line should contain the number of leaves that the water reached at the time of the query.
141 31 52 2812345678
00001122
In the sample test case:
At time 0: water is at node 1
At time 1: water has melted 1 unit of edge (1, 2), and 1 unit of edge (1, 3)
At time 3: water has completely melted edge (1, 2). The rate of melting of (1, 3) drops to 0.5 unit/second, while edge (2, 4) starts to melt at rate 1 unit/second.
At time 5: water has completely melted edge (2, 4), and the remaining edge (1, 3) has 4 units melted, 1 to go.
At time 7: Ice completely melted in all edges.
【解析】:
题意给出一棵树图,一个根节点。
用BFS思想,模拟河流流动。(最短路算法中spfa类似),得出每个节点的到达时间
然后筛选出叶子上的时间,排个序;
每当询问时,就二分查找。时间复杂度O(n*log n)
【代码】:
#include <stdio.h>#include <stdlib.h> #include <string.h> #include <iostream> #include <algorithm> #include <queue> using namespace std;typedef long long ll;const ll INF=0x3f3f3f3f3f3f3f3f;struct edge{ int u,v,cost; int next;}e[201000]; int head[110000];//链式前向星 bool leaf[110000];//标记叶子节点 ll dis[110000];//每个节点的到达时间 ll t[110000];//叶子上的时间 int spfa(){ dis[1]=0; queue<int> q; //装起点 q.push(1); while(!q.empty()) { int u=q.front(); q.pop(); ll minlen=INF; for(int i=head[u];i!=-1;i=e[i].next) //找最近的孩子节点 { if(minlen>e[i].cost) minlen=e[i].cost; q.push(e[i].v); } for(int i=head[u];i!=-1;i=e[i].next) //算时间 { int v=e[i].v; dis[v]=dis[u]+1*minlen+2*(e[i].cost-minlen); } }} int main() {ll T,n,Q,q;cin>>T;while(T--){cin>>n; memset(head,-1,sizeof(head)); memset(leaf,true,sizeof(leaf));//都是叶子 int top=1; for(int i=1;i<n;i++)//n条边的输入 { int u,v,cost; scanf("%d%d",&u,&cost); top++; leaf[u]=false;//不是叶子 e[i].u=u; e[i].v=top; e[i].cost=cost; e[i].next=head[u];//u->v head[u]=i; } spfa(); //最短路算法求出每个节点的到达时间 top=0; for(int i=1;i<=n;i++)//把叶子时间挑出来排序,然后二分查找出答案 { if(leaf[i]) t[top++]=dis[i];}sort(t,t+top); cin>>Q; while(Q--)//Q次询问 {cin>>q;int l=upper_bound(t,t+top,q)-t; cout<<l<<endl;} } return 0; }
- ACM暑假训练codeforces A. Arcade Game D. Frozen Rivers(康托展开式,spfa)
- A. Arcade Game
- Gym 100814A---Arcade Game
- hdu1430 魔板 (BFS+康托展开式)
- 1151. 魔板(BFS+康托展开式)
- 算法之康托展开式(正规)
- 康托展开式
- 康托展开式
- 康托展开式
- 八数码(A*+路径输出+逆序数+康托展开式hash)
- 算法之康托展开式
- ACM暑假训练总结
- hpu暑假训练D
- Arcade Game Gym
- UVa 11525 - Permutation (线段树 树状数组 康托展开式)
- 蓝桥杯模拟赛--康托展开式--全排列(不重复数据)
- 蓝桥杯2017【模拟赛3】排列序数(康托展开式)
- hpu暑假训练A
- Linux环境源码编译安装SVN
- QNX system architecture 6
- webpack 2.0
- Hbase对数据表的增删改查和对数据的增删改查
- Kafka 消息偏移量的维护
- ACM暑假训练codeforces A. Arcade Game D. Frozen Rivers(康托展开式,spfa)
- n后问题————回溯法求解(递归与非递归)
- mysql replace into 遇上主键自增
- use python to sendmail
- nutch2二次开发笔记
- JAVA函数实现任意给定一组数, 找出任意数相加等于某数或者在一个范围
- 正则中出现多个贪婪模式
- 外观模式 | Facade Pattern
- 设计模式之单例模式