A 水题,直接暴力模拟即可。
#include
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=40000;
typedef long long ll;
int main(int argc, char const *argv[])
{
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
ll ans=0,a,b;
for(int i=0;i
<此处应有代码>
C题 :给定一个长度为L的木棒,每次可以截取最长位D的长度,当剩下长度<=d的时候截取结束,要求达到要求所需要的截取次数的期望。
计算概率,这题正统做法我不会,然后根据别人的提示log(2)=0.693147,然后找到了规律,就这还忽略了l
#include
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int maxn=40000;
typedef long long ll;
const double eps=1e-6;
int main(int argc, char const *argv[])
{
int T;
scanf("%d",&T);
while(T--){
double l,d;
scanf("%lf %lf",&l,&d);
if(l-d
D Lucky Coins
题意:有n个种类的硬币,每i种硬币有num[i]个,掷硬币正面朝上的概率为p[i]。
现在对这n种硬币进行依次进行投掷,如果最后只剩下一种硬币,那么这种硬币就为Lucky Coins,问每一种硬币成为Lucky Coins的概率是多少。
思路的话十分简单,首先,我们先计算出到达第k步的时候硬币i死亡的概率 kill[i][j]=(1−p[i]j)num[i]
我们就可以计算出到达第i步之后i存活的概率 recv[i][j]=1−kill[i][j]
那么,我们就可以得到某一个硬币i成为lucky coins的概率 ans[i]=∑j=1max(recv[i][j]−recv[i][j+1)∗∏k=0,k≠inkill[k][j]
这个max是如何确定呢,我们知道所有的概率都在0.4-0.6之间,而总的硬币的个数在100000之内,我们就可以计算收敛的速度了。
#include
using namespace std;
typedef long long ll;
const double eps=1e-6;
const int maxn=10005;
const int maxm=100005;
double kill[12][100000],p[12],live[12][100000],ans[15];
int num[12];
int main(int argc, char const *argv[])
{
int T;
scanf("%d",&T);
while(T--){
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++){
scanf("%d %lf",&num[i],&p[i]);
}
memset(kill,0,sizeof(kill));
memset(live,0,sizeof(live));
memset(ans,0,sizeof(ans));
if(n==1){
printf("%.6f\n",1.0);
}
else{
for(int i=1;i<=n;i++){
double tmp=p[i];
for(int j=1;j<=100;j++){
kill[i][j]=pow(1-tmp,num[i]);
live[i][j]=1-kill[i][j];
tmp*=p[i];
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=75;j++){
double tmp=1.0;
for(int k=1;k<=n;k++){
if(k!=i){
tmp*=kill[k][j];
}
}
ans[i]+=(live[i][j]-live[i][j+1])*tmp;//计算只在第j轮存活的概率
}
}
for(int i=1;i<=n;i++){
printf("%.6f%c",ans[i],i==n?'\n':' ');
}
}
}
return 0;
}