AtCoder Beginner Contest 234

Posted zhy-cx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder Beginner Contest 234相关的知识,希望对你有一定的参考价值。

AtCoder Beginner Contest 234

A - Weird Function

思路分析:

  • 直接写就行

代码如下:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
ll f(ll x)

        return x * x + 2 * x + 3;

int main()

        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        ll x;
        cin >> x;
        cout << f(f(f(x) + x) + f(f(x))) << endl;
        return 0;

B - Longest Segment

思路分析:

  • \\(o(n^2)暴力即可\\)

代码如下:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 110;
ll x[maxn], y[maxn];
int main()

        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int n;
        cin >> n;
        for (int i = 0; i < n; i++)
        
                cin >> x[i] >> y[i];
        
        double d = 0.0;
        for (int i = 0; i < n; i++)
        
                for (int j = 0; j < n; j++)
                
                        double tmp = sqrt((x[j] - x[i]) * (x[j] - x[i]) + (y[j] - y[i]) * (y[j] - y[i]));
                        d = max(d, tmp);
                
        
        printf("%.10f\\n", d);
        return 0;

C - Happy New Year!

思路分析:

  • 首先找规律我们可以知道,n = 1时只有2,n = 2、3时只有20、22,n = 4、5、6、7时只有200、202、220、222,刚好对应这n的二进制修改,即将一个数的二进制求出来,然后把1替换为2输出即可

代码如下:

#include <bits/stdc++.h>
using namespace std;
int main()

        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        long long s;
        cin >> s;
        string tmp = "";
        while (s >= 1)
        
                if (s % 2 == 0)
                
                        tmp = "0" + tmp;
                
                else
                        tmp = "2" + tmp;
                s /= 2;
        
        cout << tmp << endl;
        return 0;

D - Prefix K-th Max

思路分析:

  • 给你1~n的排列,然后要你求前k、k+1、k+2...n项第k大的数
  • 首先我们可以这样想,如果是求前k项中第k大的数的话,实际上就是求前k项最小的数,然后我们去看k+1项,如果k+1项比上一次输出的结果要小的话,那么实际上这个序列的第k大的数依然不变,直接输出即可;如果k+1项比上一次输出结果大的话,那么我们可以知道的是,它肯定会改变结果,所以我们直接把他插入一个set中去找比上次输出答案大的第一个数即可。

代码如下:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 5e5 + 20;
int p[maxn];
set<int> v;
int main()

        ios::sync_with_stdio(0);
        cin.tie(0);
        cout.tie(0);
        int n, k;
        cin >> n >> k;
        for (int i = 0; i < n; i++)
        
                cin >> p[i];
        
        //先得到前面的
        sort(p, p + k);
        for (int i = 0; i < k; i++)
        
                v.insert(p[i]);
        
        int ans = p[0];
        cout << ans << endl;
        for (int i = k; i < n; i++)
        
                if (p[i] > ans)
                
                        v.insert(p[i]);
                        ans = *v.upper_bound(ans);
                        cout << ans << endl;
                
                else
                        cout << ans << endl;
        
        return 0;

E - Arithmetic Number

思路分析:

  • 一开始没想出来可以直接暴力,想的是找规律,但是碍于方向错了,所以这题没过
  • 看题解发现原来就是暴力,我们只需要把满足条件的数放入到set里面,再用lower_bound就可以求出来结果了
  • 具体怎么暴力:首先对于第一位肯定是1-9,公差我们也很容易想到是-9~8,所以我们只需要枚举第一位和公差即可,如果这个数满足我们就把它压入到set中,注意我们是先枚举第一位是啥,再枚举公差是啥,再枚举有多少位,在这个过程中,我们要用到string来存储每轮循环得到的满足条件的数(每次添加一位满足条件的数知道不能添加循环结束),然后每轮都要把结果转化位数存入到set里面就可以了

代码如下:

#include <bits/stdc++.h>
#define ll long long
using namespace std;
set<ll> solve()

        set<ll> res;
        for (int fir = 1; fir <= 9; fir++)
        
                for (int d = -9; d <= 8; d++)
                
                        string s;
                        int dg = fir;
                        for (int i = 0; i < 18; i++)
                        
                                s.push_back(dg + \'0\');
                                res.insert(stoll(s));
                                dg += d;
                                if (!(0 <= dg && dg <= 9))
                                
                                        break;
                                
                        
                
        
        return res;

int main()

        set<ll> ans = solve();
        ll x;
        cin >> x;
        cout << *ans.lower_bound(x) << endl;
        return 0;


F - Reordering

思路分析:

  • 这个题目是dp和组合数学混合一起的,难度还算比较大,首先我们肯定是要预处理逆元啥的,这里就不说了,重点还是状态转移
  • \\(dp_i,j\\)指的是用到了前i个字符(这个”个“指的是26个小写字母的前几个),构成的长度为j的字符串的数量,所以我们答案肯定就是\\(\\sum_i = 1^s.length()dp_26,i\\)
  • 那么对于\\(dp_i,j\\)我们怎么得到呢?首先我们可以通过少用一种字母即\\(dp_i - 1,j\\),也可以少用前面已经构成好的串里删去某个字符换上当前第i个字符(第i种),这样的话就是\\(dp_i - 1,j - 1\\times C_j^1\\),依次类推,可以删去1,2...min(cnt[i],j)个字符也就是说最后\\(dp_i,j\\) = \\(\\sum_k = 0^min(j,cnt[i])dp_i - 1,j - k\\times C_j^k\\)
  • 综上即可得出答案

代码如下:

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int MAX = 5010, mod = 998244353;
vector<int> fac, finv, inv;
int cnt[26];
int dp[27][MAX];
void init()

        fac.resize(MAX);
        finv.resize(MAX);
        inv.resize(MAX);
        fac[0] = fac[1] = 1;
        inv[1] = 1;
        finv[0] = finv[1] = 1;
        for (int i = 2; i < MAX; i++)
        
                fac[i] = fac[i - 1] * i % mod;
                inv[i] = mod - mod / i * inv[mod % i] % mod;
                finv[i] = finv[i - 1] * inv[i] % mod;
        

int c(int n, int m)

        return fac[n] * finv[m] % mod * finv[n - m] % mod;
 // c(n,m)
signed main()

        init();
        string s;
        cin >> s;
        int n = s.length();
        for (int i = 0; i < n; i++)
        
                cnt[s[i] - \'a\']++;
                //统计一下每个字母的数量
        
        dp[0][0] = 1;
        for (int i = 0; i < 26; i++)
        
                for (int j = 0; j <= n; j++)
                
                        for (int k = 0; k <= min(j, cnt[i]); k++)
                        
                                dp[i + 1][j] += dp[i][j - k] * c(j, k);
                                dp[i + 1][j] %= mod;
                        
                
        
        int ans = 0;
        for (int i = 1; i <= n; i++)
        
                ans = (ans + dp[26][i]) % mod;
        
        cout << ans << endl;
        return 0;

以上是关于AtCoder Beginner Contest 234的主要内容,如果未能解决你的问题,请参考以下文章

AtCoder Beginner Contest 234

AtCoder Beginner Contest 115 题解

AtCoder Beginner Contest 154 题解

AtCoder Beginner Contest 103

AtCoder Beginner Contest 228

AtCoder Beginner Contest 242