AtCoder ABC215简易题解

#链接
https://atcoder.jp/contests/abc215/tasks

A 题

链接

https://atcoder.jp/contests/abc215/tasks/abc215_a

题解

签到水题。
给一个字符串,判断是否是 Hello,World!。

AC代码

#include 
 
using namespace std;
 
typedef long long LL;
typedef pair<LL, LL> PLL;
 
const LL INF=4e18;
const int MAXN=1e6+10;
 
int main() {
#if 0
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#endif
#if 0
    freopen("00.in", "r", stdin);
    freopen("00.out", "w", stdout);
#endif
    string s;
    getline(cin, s);
    if (s=="Hello,World!") {
        cout<<"AC\n";
    } else {
        cout<<"WA\n";
    }
 
    return 0;
}

B 题

链接

https://atcoder.jp/contests/abc215/tasks/abc215_b

题解

给一个 n n n,找最大的整数 k k k,满足 2 k ≤ n 2^k \leq n 2kn
由于本题的 n n n 很小,只有 1 0 18 10^{18} 1018,因此可以使用暴力求解。

AC 代码

#include 

using namespace std;

typedef long long LL;
typedef pair<LL, LL> PLL;

const LL INF=4e18;
const int MAXN=1e6+10;

int main() {
#if 1
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#endif
#if 0
    freopen("00.in", "r", stdin);
    freopen("00.out", "w", stdout);
#endif
    LL n;
    cin>>n;
    LL k=0;
    LL ans=1;
    while (ans<=n) {
        k++;
        ans*=2;
    }
    cout<<k-1<<"\n";

    return 0;
}

C题

链接

https://atcoder.jp/contests/abc215/tasks/abc215_c

题解

给一个字符串 S S S,求第 K K K 小的字典序字符串。
本题的 S S S 长度只有 8 8 8,也就意味着最多是 8 ! = 40 , 320 8!=40,320 8!=40,320 种答案。因此,我们只需要列出所有的全排列,然后输出第 K K K 小的即可。
最简单的方法就是使用 STL 的 next_permutation() 函数。当然也可以使用 dfs 来解。

AC代码

#include 

using namespace std;

typedef long long LL;
typedef pair<LL, LL> PLL;

const LL INF=4e18;
const int MAXN=1e5+10;
string ans[MAXN];

int main() {
#if 1
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
#endif
#if 0
    freopen("00.in", "r", stdin);
    freopen("00.out", "w", stdout);
#endif
    string s;
    LL K;
    cin>>s>>K;
    sort(s.begin(), s.end());

    LL cnt=0;
    do {
        ans[++cnt]=s;
        //cout<
    } while (next_permutation(s.begin(), s.end()));
    //cout<
    cout<<ans[K]<<"\n";
    return 0;
}

D题

链接

https://atcoder.jp/contests/abc215/tasks/abc215_d

题解

N N N 个正整数 A 1 ,   A 2 ,   … ,   A N A_1,\ A_2,\ \dots,\ A_N A1, A2, , AN,找出所有从 1 1 1 k k k,满足 gcd ( A i , k ) = 1 \text{gcd}(A_i, k)=1 gcd(Ai,k)=1
本题要求找出任意一个 k k k 和数组 A A A 的所有元素互质。
如果本题使用暴力求解,即枚举所有的 1 ∼ m 1 \sim m 1m 中的所有数据,使得其满足题目要求。但是由于 n ,   m n,\ m n, m 的大小为 1 0 5 10^5 105,这个算法的时间复杂度为 O ( m ∗ n ) O(m*n) O(mn),因此最大情况需要计算 1 0 5 ∗ 1 0 5 = 1 0 10 10^5 *10^5=10^{10} 105105=1010,这样的计算量即使是 2 2 2s 也是要超时的。
注意到本题的 A i A_i Ai 取值范围是 1 ∼ 1 0 5 1 \sim 10^5 1105,也就是说这个值域非常小。所以我们可以先用筛法筛出 1 0 5 10^5 105 中所有质数。然后再遍历 m m m

AC代码

#include 

using namespace std;

typedef long long LL;
typedef pair<LL, LL> PLL;
const int MAXN=1e5+10;
vector<bool> exist(MAXN, false);//数据i是否出现
vector<bool> ispri(MAXN, true);//数据i是否是质数

int main() {
#if 1
   ios::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
#endif
#if 0
    freopen("00.in", "r", stdin);
    freopen("00.out", "w", stdout);
#endif
   LL n,m;
   cin>>n>>m;

   //筛法初始化
   ispri[0]=ispri[1]=false;//质数

   for (LL i=1; i<=n; i++) {
      LL val;
      cin>>val;
      exist[val]=true;
   }

   //找出范围内所有质数
   for (LL i=2; i<MAXN; i++) {
      if (!ispri[i]) {
         exist[i]=false;
         continue;
      }
      for (LL j=i; j<MAXN; j+=i) {
         ispri[j]=false;
         if (exist[j]) {
            exist[i]=true;
            break;
         }
      }
   }

   //遍历可能的结果
   vector<bool> possible(m+1, true);
   possible[0]=false;
   for (LL i=2; i<=m; i++) {
      if (!exist[i]) {
         continue;
      }
      for (LL j=i; j<=m; j+=i) {
         possible[j]=false;
      }
   }

   LL cnt=0;
   for (LL i=1; i<=m; i++) {
      if (possible[i]) {
         cnt++;
      }
   }
   cout<<cnt<<"\n";
   for (LL i=1; i<=m; i++) {
      if (possible[i]) {
         cout<<i<<"\n";
      }
   }

   return 0;
}

E题

链接

https://atcoder.jp/contests/abc215/tasks/abc215_e

题解

这题是竞赛后完成的。阅读完后,这题是一个 bit DP 题目。惨,bit DP 早就忘记了。还好,本题算 bit DP 的模板题,直接套用模板即可。
对应的状态方程如下:
d p [ i ] [ u ] [ j ] = d p [ i − 1 ] [ u ] [ j ] dp[i][u][j]=dp[i-1][u][j] dp[i][u][j]=dp[i1][u][j]
其中: i i i 表示竞赛的编号, u u u 表示所有的集合, j j j 表示竞赛的种类。

AC代码

#include 

using namespace std;
typedef long long LL;
const int MAXN=1024;
LL dp[MAXN][MAXN][12];

const LL MOD=998244353;

int main(){
#if 1
   ios::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
#endif
   LL n;
   string s;
   cin>>n>>s;

   for(LL i=1;i<=n;i++){
      LL x=s[i-1]-'A';
      for(LL u=0; u<MAXN;u++){
         for(LL j=0;j<10;j++){
            dp[i][u][j]=dp[i-1][u][j];
            if(j==x){
               dp[i][u][j]+=dp[i-1][u][j];
               dp[i][u][j]%=MOD;
            }
         }
      }

      for(LL v=0;v<MAXN;v++){
         if(v&(1<<x)){
            continue;
         }
         for(LL j=0;j<10;j++){
            dp[i][v|(1<<x)][x]+=dp[i-1][v][j];
            dp[i][v|(1<<x)][x]%=MOD;
         }
      }

      dp[i][(1<<x)][x]++;
      dp[i][(1<<x)][x]%=MOD;
   }

   LL res=0;
   for(LL u=0;u<MAXN;u++){
      for(LL j=0;j<10;j++){
         res+=dp[n][u][j];
         res%=MOD;
      }
   }
   cout << res << '\n';

   return 0;
}

F题

链接

https://atcoder.jp/contests/abc215/tasks/abc215_f

题解

吐槽一下,F 题竟然比 E 题简单。
题目要求我们找所有最大问题的最小值,直接使用二分答案即可。
根据题目可知: min ( ∣ x i − y i ∣ ,   ∣ x j − y j ∣ ) ≥ K → ∣ x i − y i ∣ ≥ K  &&  ∣ x j − y j ∣ ≥ K \text{min}(|x_i-y_i|,\ |x_j-y_j|) \geq K \rightarrow |x_i-y_i| \geq K\ \text{\&\&}\ |x_j-y_j| \geq K min(xiyi, xjyj)KxiyiK && xjyjK

AC代码

#include 
using namespace std;
typedef long long LL;
typedef pair<LL, LL> PLL;
const LL INF=4e18;

int main(){
#if 1
   ios::sync_with_stdio(0);
   cin.tie(0);
   cout.tie(0);
#endif
   LL n; 
   cin >> n;
   vector<PLL> v(n);
   for (LL i = 0; i < n; i++) {
      cin >> v[i].first >> v[i].second;
   }
   sort(v.begin(), v.end());

   LL ok = 0, ng = INF;
   while(ng - ok > 1){
      LL md = (ok + ng)/2;
      queue<PLL> que;
      bool able = false;
      LL mi = INF, ma = 0;
      for (auto p:v){
         while(!que.empty()){
            if(que.front().first > p.first - md) {
               break;
            }
            mi = min(mi, que.front().second); 
            ma = max(ma, que.front().second);
            que.pop();
         }
         if(mi <= p.second - md || ma >= p.second + md) {
            able=true;
         }
         que.push(p);
      }
      if(able) {
         ok = md;
      } else {
         ng = md;
      }
   }
   cout << ok << endl;
   return 0;
}

总结

我太难了,所有的东西都忘记了。人生艰难,连 ABC 都没法 AK 了。惨。

你可能感兴趣的:(OJ题解,#,AtCoder题解,OJ题解,ABC215,AtCoder)