A - Appeal to the Audience
题意:
判断:树,节点,父节点emmmm签到签到
B - Breaking Branches
题意:给定一长度为n的线段,Alice和Bob轮流切割线段使之成为两个整数段,最后进行切割的人获胜。若Alice 胜,输出“Alice”,和第一步操作数;否则输出“ Bob”。
所以就是切到最后两端都为1,看谁切最后一刀
判断:n的长度要切n-1刀
#include<iostream>
#include<cstring>
using namespace std;
int main(){
int n;
cin>>n;
if(n%2==0)
cout<<"Alice"<<endl<<n-1<<endl;
else
cout<<"Bob"<<endl;
}
C
D
E - Efficient Exchange
题意:只有整型钞票,都是十的倍数,还有一,然后有好几种方法交易,问怎么样交易的纸币数量最少,一也是纸币
判断:我先想的正着走,结果进位什么的进的我头大,然后反正是最值问题,就想到用动规,对于每一位数字来说前一位数字都会影响这一位数字的值,所以就能构成状态,状态又分进位和不进位以及他上一位数进位还是不进位,然后动规
应该是最短代码了
#include<iostream>
#include<cstring>
using namespace std;
int dp[10000][10000];
int main(){
string str;
int n;
cin>>str;
n=str.length();
dp[0][0]=0;
dp[0][1]=1;
for(int i=0;i<n;i++){
dp[i+1][0]=min(dp[i][0]+str[i]-'0',dp[i][1]+10-str[i]+'0');
dp[i+1][1]=min(dp[i][0]+str[i]-'0'+1,dp[i][1]+9-str[i]+'0');
}
cout<<dp[n][0]<<endl;
}
F - Find my Family
题意:Alice比我高在我左边Bob比我俩都高在我右边,给你一堆照片,问符合条件的一共有几张,并输出是第几张照片符合条件
判断:据(●—●)的笔记分析
维护单调上升序列,每次加入元素前的删除元素记录所删除的最后一个值,每次删之前拿新元素和这个值比较,如果新元素大则这组数据合法。摘自(●—●)笔记
有歧义啊,应该是中间隔着人没关系,也算是符合,代码是解决这个问题的
#include <bits/stdc++.h>
using namespace std;
int k,n,h[300005],pos,que[300005],ac[1005],num,tmp;//que来暂存可能的Alice和我
int main()
{
cin>>k;
for(int i=1;i<=k;i++)
{
scanf("%d",&n);
bool ans=0;
pos=0;
tmp=(1e9)+1;//暂存比较数列
for(int j=1;j<=n;j++)
{
scanf("%d",&h[j]);
while(pos&&que[pos]>=h[j])//上一个数大
tmp=que[pos--];//暂存前前数
if(h[j]>tmp) ans=1;//刚输入的这个比他前前面都大,ans就是true
que[++pos] = h[j];//相当于pos一直维持在1-3
}
if(ans)//这张照片符合条件
ac[++num]=i;
}
cout<<num<<endl;
for(int i=1;i<=num;i++)
cout<<ac[i]<<endl;
return 0;
}
G - Gluttonous Goop
题意:有个菌种会感染周围八个宫格,
判断:当时我看到以为是bfs,结果网上题解都说是线段树那只能待补题了
H - Historic Exhibition
题意:给花瓶,给展台然后匹配问题
判断:刚开始猛上去就是二分匹配法,结果匈牙利算法太大了,需要简化,看(●—●)的题解是要用网络流,然而这是我目前无法get的领域
I
J - Jazz it Up!
题意:输入n,2<=m<n,2<=k&&kk<mn,求符合条件的任意一个m即可
判断:水题,就是题意比较难看懂
#include <bits/stdc++.h>
using namespace std;
int main(){
int n,flag;
cin>>n;
for(int m=2;m<n;m++)
{
flag=0;
for(int k=2;k*k<n*m;k++)
{
if((m*n)%(k*k)==0)
flag=1;
}
if(flag==0)
{
cout<<m;
return 0;
}
}
}
K
L - Lucky Draw
题意:2<=n<=50个人, 1≤k≤50条命,0.1≤p≤0.9 点存活概率,有n个人玩游戏,每个人拥有k条生命。每轮每个人会有p的概率不会死,求最后是平局的概率
判断:看了网上的题解,万万没想到会是一道动规,这藏得比E还深啊,压根没往动规想,灵感还是很重要的
搬运判断:设f[i][j]表示i轮后剩余j条生命的概率,那么 f[i][j] = p * f[i - 1][j] + (1 - p) * f[i - 1][j + 1]
由于生命都相同,P(平局) = 1 - P(某人赢) = 1 - n* P(第一个人赢) = 1 - n * sum( P(第一个人第i轮赢其余人i-1轮死) )
————————————————
版权声明:本文为CSDN博主「moomhxy」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_41785863/article/details/105069753
#include<bits/stdc++.h>
using namespace std;
double f[1005][1005];
int main(){
int n,m;
double p;
cin>>n>>m>>p;
f[0][m]=1;//第0轮后剩余m条生命的概率是1
for(int i=1;i<1005;++i)//等下试一下++i和i++的区别
{//这些是针对一个人的
for(int j=m;j>0;j--)
f[i][j]=p*f[i-1][j]+(1-p)*f[i-1][j+1];//第i轮过后还有j条命的概率=前一轮保命的概率+前一轮丢命的概率
f[i][0]=f[i-1][0]+(1-p)*f[i-1][1];//生命耗尽时不用乘以概率,前一次如果是保命继承的话,必定是百分之百概率
}
double ans=0;//平局的概率
for(int i=1;i<1005;++i)//一千次以后的概率对答案的影响很小
{
ans+=(f[i][0]-f[i-1][0])*pow(f[i-1][0],n-1);//计算在i轮死亡并且其他人都在i轮之前死亡的概率
}
printf("%.10f\n", 1 - n * ans);//对每个人都要满足计算在i轮死亡并且其他人都在i轮之前死亡的概率
return 0;
}