记录编号 133523 评测结果 AAAAAAAAAAAAAAAAAAAA
题目名称 [国家集训队2012]Contra 最终得分 100
用户昵称 Gravatarcstdio 是否通过 通过
代码语言 C++ 运行时间 0.861 s
提交时间 2014-10-28 09:36:24 内存使用 0.31 MiB
显示代码纯文本
  1. #include<iostream>
  2. #include<cstdio>
  3. #include<algorithm>
  4. #include<cstring>
  5. using namespace std;
  6. const int SIZE_MT=40;
  7. class MATRIX{
  8. public:
  9. int n,m;
  10. double s[SIZE_MT][SIZE_MT];
  11. void clear(int a,int b){n=a,m=b;for(int i=0;i<a;i++){for(int j=0;j<b;j++){s[i][j]=0;}}}
  12. void clearunit(int a){clear(a,a);for(int i=0;i<a;i++) s[i][i]=1;}
  13. };
  14. MATRIX operator * (MATRIX a,MATRIX b){
  15. MATRIX c;
  16. c.n=a.n,c.m=b.m;
  17. for(int i=0;i<c.n;i++)
  18. for(int j=0;j<c.m;j++){
  19. c.s[i][j]=0;
  20. for(int k=0;k<a.m;k++)
  21. c.s[i][j]+=a.s[i][k]*b.s[k][j];
  22. }
  23. return c;
  24. }
  25. MATRIX quickpow(MATRIX a,int n){
  26. MATRIX ans;ans.clearunit(a.n);
  27. while(n){
  28. if(n&1) ans=ans*a;
  29. a=a*a;
  30. n>>=1;
  31. }
  32. return ans;
  33. }
  34. pair<int,int> states[SIZE_MT];int stot;
  35. //其中first是u值,second是生命值
  36. int N,R,Q;
  37. double S;
  38. int findstate(int u,int q){
  39. return find(states+1,states+stot+1,make_pair(u,q))-states;
  40. }
  41. MATRIX transfer(double p){//过关概率为p
  42. MATRIX D;
  43. //0是ans
  44. D.clear(stot+1,stot+1);
  45. //D.s[i][j]代表每次转移时i对之后的j的贡献系数
  46. D.s[0][0]=1;
  47. for(int i=1;i<=stot;i++){
  48. int u=states[i].first,q=states[i].second;
  49. //过了则u++,q++
  50. D.s[i][findstate(min(u+1,R),min(q+1,Q))]=p;
  51. D.s[i][0]=p*min(u+1,R);
  52. //不过则u=0,q--
  53. if(q-1) D.s[i][findstate(0,q-1)]=1-p;
  54. }
  55. return D;
  56. }
  57. double calc(double p){
  58. MATRIX D=transfer(p);
  59. MATRIX O;O.clear(1,stot+1);
  60. O.s[0][findstate(0,Q)]=1;
  61. O=O*quickpow(D,N);
  62. return O.s[0][0];
  63. }
  64. void work(void){
  65. if(calc(1.0)<=S){
  66. printf("Impossible.\n");
  67. return;
  68. }
  69. double l=0,r=1.0;
  70. int tot=0;
  71. while(tot++<30){
  72. double mid=(l+r)/2;
  73. if(calc(mid)>=S) r=mid;
  74. else l=mid;
  75. }
  76. printf("%.6lf\n",l);
  77. }
  78. void make_states(void){//给合法状态打一张表
  79. stot=0;
  80. for(int u=0;u<=R;u++){
  81. //此时生命值>=u+1
  82. for(int j=min(u+1,Q);j<=Q;j++) states[++stot]=make_pair(u,j);
  83. }
  84. }
  85. int main(){
  86. freopen("nt2012_contra.in","r",stdin);
  87. freopen("nt2012_contra.out","w",stdout);
  88. cin>>N>>R>>Q>>S;
  89. make_states();
  90. work();
  91. return 0;
  92. }