这几天还是正常的刷题。在整理几道题吧。
hiho1075 开锁魔法
题目:舞台上有 n 个盒子,每个盒子中有一把钥匙,对于每个盒子而言有且仅有一把钥匙能打开它。初始时,崔克茜将会随机地选择 k 个盒子用魔法将它们打开。崔克茜想知道最后所有盒子都被打开的概率,你能帮助她回答这个问题吗?
可以看出,如果打开其中一个置换环的一个,那么整个换都开了,所以先处理出该数组有r个集合,将每个集合容量存入数组,然后用dp[i][j]表示前i个环用j个魔法打开有多少种情况,那么 dp[i][j]=Σ dp[i-1][j-k]*C[ai][k] (1<=k<=ai)。
代码:
int a[305],c[305];
double dp[305][305];
int vis[305];
double C[305][305];
int main()
{
memset(C,0,sizeof(C));
for(int i=0;i<=300;i++)
{
C[i][0]=C[i][i]=1.0;
for(int j=1;j<i;j++)
C[i][j]=C[i-1][j-1]+C[i-1][j];//预处理C(n,m),利用帕斯卡原理
}
int T;
scanf("%d",&T);
while(T--)
{
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++) scanf("%d",&c[i]);
memset(vis,0,sizeof(vis));
int r=0;
for(int i=1;i<=n;i++)//处理出来所有环,记录容量
{
if(!vis[i])
{
int t=i,cnt=0;
while(1)
{
if(vis[t]) break;
cnt++;
vis[t]=1;
t=c[t];
}
a[r++]=cnt;
}
}
if(k>=r)
{
memset(dp,0,sizeof(dp));
dp[0][0]=1.0;
for(int i=0;i<r;i++)
{
for(int j=0;j<=k;j++)
{
//if(fabs(dp[i][j])<=0.000001) continue;
for(int l=1;l<=a[i]&&l+j<=k;l++)
{
dp[i+1][j+l]+=dp[i][j]*C[a[i]][l];//从第i个环中选l个
}
}
}
printf("%.5lf\n",(dp[r][k]/C[n][k]));
}
else printf("%.5lf\n",0);
}
}
hiho1717 hiho字符串3
题意:我们定义第一代hiho字符串是"h"。 第N代hiho字符串是由第N-1代hiho字符串变化得到,规则是在每一个h后插入i,i后插入o,o后插入h。 例如第二、三、四代hiho字符串分别是: "hi"、"hiio"和"hiioiooh"。给定K,请你计算第100代hiho字符串中的第K个字符是什么。
其实这个题只要写几代就能发现,第i代由i-1代增加而来,而增加的字符串就是二叉树型结构,第一百代就是一个一百层的二叉树,第i个数就是二叉树的第i个结点。就是从下至上到根节点在顺着倒回来变化就可以了。
代码:
就是明显的二叉树结构。
using namespace std;
ll a[10000001],sum[10000001],n;
char s[5]={'0','h','i','i','o'};
char change(char str)//变化次序
{
if(str=='i') return 'o';
else if(str=='o') return 'h';
else if(str=='h') return 'i';
}
char dfs(ll k,ll t)
{
if(k==2&&t==1) return 'i';
if(k==2&&t==2) return 'o';
ll w=a[k]/2;
if(t>w)
{
char q=dfs(k-1,t-w);//右支
return change(q);//右支要改变。
}
else if(t<=w)//左支
{
char q=dfs(k-1,t);
return q;
}
}
int main()
{
a[1]=1;
sum[1]=1;
ll k=2;
for(int i=2;;i++)
{
a[i]=k;
sum[i]=sum[i-1]+a[i];
k=k*2;
if(sum[i]>1e15) break;
}
int T;
scanf("%d",&T);
while(T--)
{
char ans;
scanf("%lld",&n);
if(n<=4) cout<<s[n]<<endl;
else
{
ll l,r;
for(int i=1;;i++)
{
if((sum[i]+1)>=n)
{
r=i;
l=i-1;
break;
}
}
ll e=n-sum[l]-1;
//cout<<a[r]<<endl;
char ans=dfs(r,e);
cout<<ans<<endl;
}
}
}