首页 > 其他分享 >AtCoder Beginner Contest 382 Solution

AtCoder Beginner Contest 382 Solution

时间:2024-11-30 23:46:06浏览次数:5  
标签:AtCoder int void 稀有 Solution cin 382 rep dp

题目大意

给定一个长度为N的字符串,有很多.@,一共有D天,每天会使一个@变成.,问D天之后有几个.

解题思路

数一下有几个.,答案会加D个.

代码

void solve()
{
    int n, d;
    string s;
    cin >> n >> d >> s;
    cout<<count(s.begin(),s.end(),'.')+d;
}

题目大意

题意和第一题差不多,但是每天会让最右边的@变成.,问D天之后的字符串长什么样。

解题思路

按照题意模拟即可。

代码

void solve()
{
    int n, d;
    string s;
    cin >> n >> d >> s;
    int cnt = 0;
    for(int i=(int)s.size()-1;i>=0;i--){
        if (s[i] == '@') {
            cnt++;
            s[i] = '.';
            if (cnt == d) break;
        }
    }
    cout << s;
}

C - Kaiten Sushi (abc382 C)

题目大意

题目意思很复杂,可以自己阅读一下,我这里简化题意。

给定一个长度为N的数组A,并且有M次查询B。
对于第i个查询Bi问A数组里从左往右第一个小于等于Bi的数的下标是多少

解题思路

题目是离线的,那么B数组的顺序无关紧要,把他压进一个优先队列里,然后从左向右遍历A数组,每次把所有大于等于Ai的数都弹出队列并且标记答案就可以了。

代码

#define rep(i,n) for(int i=0;i<n;i++)
priority_queue<pair<int,int> > q;
int a[200005],b[200005];
int ans[200005];
void solve()
{
    int n, m;
    cin >> n >> m;
    rep(i,n) cin>>a[i];
    rep(i,m) cin>>b[i];

    rep(i, m) q.push(make_pair(b[i], i));
    rep(i, n) {
        while (!q.empty() && q.top().first >= a[i]) {
            ans[q.top().second] = i + 1;
            q.pop();
        }
    }
    rep(i,m) cout<<ans[i]<<endl;
}

D - Keep Distance (abc382 D)

题目大意

给定N和M,按字典序输出所有满足以下条件的数组:

  • $1 \le A_i$
  • 对于i大于等于2,$A_{i-1}+10 \le A_i$
  • $A_N \le M$

解题思路

这题关键点在于$10N-9 \le M \le 10N$,那么说明中间的差其实不会超过20,否则最后一个数一定会超过M。

然后暴力即可。

代码

vector<vector<int> > ans;
int n, m;
vector<int> tmp;
void dfs(int x) {
    if (x == n) {
        ans.pb(tmp);
        return;
    }
    if (tmp[x - 1] + (n - x) * 10 > m) return;
    for (int i = 10;i <= 20;i++) {
        tmp[x] = tmp[x - 1] + i;
        if (tmp[x] > m) return;
        dfs(x + 1);
    }
}

void solve()
{
    cin >> n >> m;
    tmp.resize(n);
    for (int i = 1;i <= 10;i++) {
        tmp[0] = i;
        dfs(1);
    }
    cout << ans.size() << endl;
    //以下为auto输出ans
    for(auto v, ans) {
        for(auto i, v) cout << i << " ";
        cout << endl;
    }
}

E - Expansion Packs (abc382 E)

题目大意

一个卡牌包里有n张卡牌,第i张卡牌是稀有牌的概率是pi。

现在将一包一包的开牌,直到开出X张稀有牌为止,问开的卡牌包数的期望是多少

解题思路

看通过人数可以发现期望放在E题不是很合适。

首先求出dp[i][j]为一包中拆前i张牌,有j张是稀有牌的概率:

第i张不是稀有牌,转移:dp[i][j] = dp[i - 1][j] * (1 - p[i])
第i张是稀有牌,转移: dp[i][j] += dp[i - 1][j - 1] * p[i]

然后这个数组我们其实只用得到dp[n][i],其实也就是一整包中开出i张稀有牌的概率,所以dp其实可以滚动数组,但是这题n^2是可以存的下的。

然后设e[i]为开出i张稀有牌的期望包数(即答案)。

那么可以考虑新开出的”一包“中有几张稀有牌,我们先假设这一包不可能没有稀有牌,那么可以很简单的得到转移:e[i]=sigma(e[i-j]*dp[n][j])+1,就是开出i-j张稀有牌的期望*这一包开出j张稀有牌的概率,最后加上1表示我们新开了一包。

但是其实会开不出稀有牌,那么我们要先计算一下期望多少包一定开出稀有牌,是个简单的0-1概型:1/(1-dp[n][0]),所以式子调整成e[i]=sigma(e[i-j]*dp[n][j])+1/(1-dp[n][0]),但是此时还不对,因为内部的dp[n][j]是包含了开不出稀有牌的概率,但我们已经将开不出稀有牌的期望放在外面计算了:
所以最后的式子应该是e[i]=sigma(e[i-j]*(dp[n][j]/(1-dp[n][0])))+1/(1-dp[n][0])

好在给的样例还是很有代表性的。

代码

double dp[5005][5005];
double e[5005];
void solve() {
    int n, x;
    cin >> n >> x;
    vector<double> p(n);
    for(int i=0;i<n;i++)
        cin >> p[i];
        p[i] /= 100.0;
    }
    dp[0][0] = 1.0;
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j <= n; ++j) {
            dp[i][j] = dp[i - 1][j] * (1 - p[i - 1]);
            if (j > 0) {
                dp[i][j] += dp[i - 1][j - 1] * p[i - 1];
            }
        }
    }
    for (int i = 1;i <= x;i++) {
        for (int j = 1;j <= i;j++) {
            e[i] += (e[i - j]) * (dp[n][j] / (1.0 - dp[n][0]));
        }
        e[i] += (1.0 / (1.0 - dp[n][0]));
    }
    cout << fixed << setprecision(10) << e[x];
}

标签:AtCoder,int,void,稀有,Solution,cin,382,rep,dp
From: https://www.cnblogs.com/NightRaven/p/18579176

相关文章

  • AtCoder Beginner Contest 380 Solution
    A-1232336个数问是不是1个1,2个2,3个3#include<bits/stdc++.h>usingnamespacestd;inta[4];intmain(){strings;cin>>s;for(inti=0;i<s.size();i++)a[s[i]-'0']++;if(a[1]==1&&a[2]==2......
  • ABC382
    上午NOIP太憋屈了,我要切水恢复一下信心(希望cy别看见A-DailyCookie在题目限制中,已经确定\(S\)中@字符的个数多于\(D\)。所以我们直接数.的个数加上\(D\)就可以。时间复杂度\(O(n)\)。点击查看代码#include<iostream>#include<cstdio>usingnamespace......
  • AtCoder Beginner Contest 382 赛后复盘
    abc381的赛后总结不见了。(人话:没写)A-B模拟即可C因为好吃的会被前面的人吃掉,后面的人只能捡垃圾吃,所以实际上能吃东西的\(a\)成单调递减。所以我们直接二分在哪个区间即可,时间复杂度\(O(m\logn)\)。点击查看代码#include<bits/stdc++.h>#definelllonglong#de......
  • AtCoder Beginner Contest 382
    A-DailyCookie题意给定长为\(n\)的串,“.”代表空,“@”代表饼干,一天吃一块饼干,问\(d\)天后有几个格子是空的。思路模拟。代码点击查看代码#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongtypedefpair<int,int>pii;constintmxn=1e......
  • The solution to NOIP2024·T1——edit
    ThesolutiontoNOIP2024·T1——edithttps://www.luogu.com.cn/problem/P11361这是我在赛场想出来的思路,平时一个绿题都写不出来的题竟然一眼出思路,也真是RP++;思路由题目中的非限制的数可以互相交换,想到对于每一段连续的非限制性的区间都可以任意排布位置。那么可以把t序......
  • Atcoder Beginner Contest 330 题解
    前言过于水的一场。ACountingPasses题面给出一个长度为\(n\)的序列\(a\),求出\(a\)之中大于等于\(l\)的数个个数。\(1\len\le100,1\lea_i\le1000,1\lel\le1000\)。制約入力は全て整数$1\\le\N\\le\100$$1\\le\L\\le\1000$$0\\le\A_i\\le......
  • AtCoder Beginner Contest 381
    省流版A.按题意判断即可B.按题意判断即可C.枚举/的位置,然后分别向左右找到最长的1串和2串,然后取最小值即可D.讨论起始位置的奇偶性,然后用双指针,每两个字符每两个字符,维护出现的次数为2,两种情况取最大值即可E.答案为所有/的左右12个数的最小值的最大值,注意到个数随着/......
  • AtCoder ABC321F - #(subset sum = K) with Add and Erase 题解 可撤销背包
    题目链接:https://atcoder.jp/contests/abc321/tasks/abc321_f题目大意:给定大小为\(k\)的背包和\(q\)次操作,支持两种操作:插入一个大小为\(x\)的元素;删除一个大小为\(x\)的元素。每次操作后,求装满背包方案数。解题思路:可撤销背包。插入\(x\)时,fori=K->x......
  • Toyota Programming Contest 2024#11(AtCoder Beginner Contest 379)
    A-Cyclic链接:A-Cyclic代码:#include<bits/stdc++.h>usingnamespacestd;intmain(){ stringss; cin>>ss; cout<<ss[1]<<ss[2]<<ss[0]<<""<<ss[2]<<ss[0]<<ss[1]; return0;}B-Strawberri......
  • 【Solution】用C语言代码绘制线性函数包围图
    题目:绘制左边图的众多*输出图像,函数已给出:y=1,y=-x+2n,y=x。解决方案: 思路对于原来的坐标几何图形,2<=n,y<=x<=2n-y,1<=y<=x。我们用来写C代码的函数首先要确定三角形高的范围,至少要2。将图形分隔成上下两部分。从最高的顶点到三角形高的部分,和其下面的部分。使用line......