欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 科技 > 能源 > AtCoder Beginner Contest 402题解

AtCoder Beginner Contest 402题解

2025/4/24 12:20:50 来源:https://blog.csdn.net/2301_80475191/article/details/147464547  浏览:    关键词:AtCoder Beginner Contest 402题解

A - CBC

思路:仔细看这题其实就发现,我们只需要遍历一遍字符串把大写字母输出即可,很标准的签到题

#include<bits/stdc++.h>
using namespace std;
#define int long longsigned main()
{string s;cin>>s;for(char c:s){if(c>='A'&&c<='Z'){cout<<c;}}return 0;
}

 B - Restaurant Queue

思路:直接用双端队列deque模拟一遍直接过

 

#include<bits/stdc++.h>
using namespace std;
#define int long long 
deque<int> que;
int q;
int x;
int flag;
signed main()
{cin>>q;while(q--){cin>>flag;if(flag==1){cin>>x;que.push_back(x);}else{cout<<que.front()<<"\n";que.pop_front();}}return 0;
}

C - Dislike Foods

思路:我们可以用map去存储第i个食材在第几天克服,因此我们可以知道每个菜最早在第几天可以吃,我们将第i天可以吃的食物累加起来,最后跑一遍累加和直接解决问题

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
vector<int> e[300005];
map<int,int> mp;//每个食材是第几天的 
map<int,int> day;//第几天解锁当前菜品 
signed main()
{cin>>n>>m;for(int i=1;i<=m;i++){int k;cin>>k;for(int j=1;j<=k;j++){int x;cin>>x;e[i].push_back(x);}}for(int i=1;i<=n;i++){int x;cin>>x;mp[x]=i;}for(int i=1;i<=m;i++){int ans=0;for(int j:e[i]){ans=max(ans,mp[j]);}day[ans]++;} int sum=0;for(int i=1;i<=n;i++){sum+=day[i];cout<<sum<<"\n";}return 0;
}

D - Line Crossing

思路:我们发现只要不在一条水平线上就肯定会相交,我们考虑一下加入给你n条线段,n条线段都互不平行,那么最后会有多少种这个满足的线对呢?答案是肯定的n*(n-1)/2,那么我们只需要减去平行线段多余的贡献即可

这题的考点在于如何去判断两条直线是平行的,如果我们足够仔细,我们会发现其实线段中其实也就只会出现n种斜率,刚好对应端点数,我们只需要判断其两个端点的和取模n的数即可,我们用cnt数组去存储(a+b)%n即可,然后我们在在总满足线对中,减去同斜率的端点对即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,m;
int cnt[1000005];
signed main()
{cin>>n>>m;int ans=m*(m-1)/2;for(int i=1;i<=m;i++){int a,b;cin>>a>>b;cnt[(a+b)%n]++;}for(int i=0;i<n;i++){ans-=cnt[i]*(cnt[i]-1)/2;}cout<<ans;return 0;
}

 E - Payment Required

思路:一个状压+概率dp的一个问题 

我们看数据n<=8,一眼就看出来需要用状态压缩我们可以考虑当前已经选择的当前的状态用二进制存储即可,然后我们考虑dp的状态是什么,dp[i][j]表示剩下i元,选择的状态为j的最大期望,然后我们只需要在第一层循环去遍历剩下多少钱,第二层循环遍历状态,第三层循环去遍历要加入的点即可

然后我们考虑一下状态转移方程式

当前选择k做对的概率为p[k]

那么当前选择k做错的概率为(1-p[k])

那么我们当前胜利获得的期望为s[k]+dp[i-c[k]][j|(1<<k)]

那么我们当前失败所得期望为dp[i-c[k]][j]

因此我们总的期望=对的概率*对的期望+错的概率*错的期望

我们之间跑即可

最后输出dp[n][0]即可

#include<bits/stdc++.h>
using namespace std;
#define int long long
int n,x;
int s[10];
int c[10];
int p[10];
double dp[5005][1 << 10];
signed main()
{cin >> n>>x;for (int i = 0; i < n;i++){cin >> s[i] >> c[i] >> p[i];}for (int i = 0; i <=x;i++){for (int j = 0; j < (1 << n); j++){double ans = 0;for (int k = 0; k < n;k++){if((j>>k)&1||c[k]>i){continue;}double pi = p[k] / 100.0;double suc = s[k] + dp[i - c[k]][j|(1<<k)];double fal = dp[i - c[k]][j];ans = max(ans, pi * suc + (1 - pi) * fal);}dp[i][j] = ans;}}cout << fixed << setprecision(10) << dp[x][0] << endl;return 0;
}

 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词