Educational Codeforces Round 129 (Rated for Div. 2) (A-D)题解

244 阅读2分钟

A. Game with Cards

题意: Alice 和 Bob 手上有一些牌,谁的牌大谁赢,如果相等,谁先出谁赢。

#include <iostream>
#include <cstring>
#include <set>
#include <map>
using namespace std;

const int N = 2e5+5;

char a[N];

void solve(){
   int n, maxX = 0;
   cin>>n;
   for(int i=0; i<n; i++){
       int x;
       cin>>x;
       maxX = max(x, maxX);
   }
   int m, maxY = 0;
   cin>>m;
   for(int i=0; i<m; i++){
       int y;
       cin>>y;
       maxY = max(y, maxY);
   }
   if(maxX > maxY){
       cout<<"Alice"<<endl;
       cout<<"Alice"<<endl;
   }else if(maxX < maxY){
       cout<<"Bob"<<endl;
       cout<<"Bob"<<endl;
   }else{
       cout<<"Alice"<<endl;
      cout<<"Bob"<<endl;
   }
}
int main() {
    int t;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

B. Card Trick

题意:一个有序的队列,给一个长度的 m 的数组 aa, 每次将前 a[i]a[i] 个元素移动到队尾,问第一个元素的谁? 题解:把队列看成一个环形,每次操作可以当成指针的移动。求和%n。

#include <iostream>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 2e5+5;

char a[N];

void solve(){
  int n;
  cin>>n;
  vector<int> f(n);
  for(int i=0; i<n; i++){
      cin>>f[i];
  }
  int m;
  cin>>m;
 long long sum = 0;
  for(int i=0; i<m; i++){
      int k;
      cin>>k;
      sum += k;    
  }
  sum = sum % n;
  cout<<f[sum]<<endl;
}
int main() {
    int t;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

C. Double Sort

题意:2 个有 n 个元素的数组 aabb1<=i,j<=n(ij)1 <= i, j <=n (i\not=j), 可以交换 iijj 列,使得数组 aabb 都是为非递减数组。
题解: 数组 aa 前面元素比后面大的就 数组 aa 和数组 bb 各自交换, 记录ij(i, j),数组 bb 同理,类似冒泡排序,最后看 aabb 是否有序,有序输出(i,j),否则1-1

#include <iostream>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
using namespace std;

const int N = 105;

int a[N], b[N];

void solve(){
    int n;
    cin>>n;
    for(int i=1; i<=n; i++) cin>>a[i];
    for(int i=1; i<=n; i++) cin>>b[i];
    
    vector<pair<int, int>> v;
    for(int i=1;i<=n; i++){
        for(int j=i+1; j<=n; j++){
            if(a[i] > a[j]){
                v.push_back({i, j});
                swap(a[i], a[j]);
                swap(b[i], b[j]);
            }
        }
    }
    
     for(int i=1;i<=n; i++){
        for(int j=i+1; j<=n; j++){
            if(b[i] > b[j]){
                v.push_back({i, j});
                swap(a[i], a[j]);
                swap(b[i], b[j]);
            }
        }
    }
    if(is_sorted(a+1, a+n+1) && is_sorted(b+1, b+n+1)){
        cout<<v.size()<<endl;
       for(auto c : v){
            cout<<c.first<<" "<<c.second<<endl;
        }
    }else{
        cout<<-1<<endl;
    }
    
}
int main() {
   int t;
   cin>>t;
   while(t--){
        solve();
   }
    return 0;
}

D. Required Length

题意: 给一个 n 和 x, 从 x 十进制中任选一位 yy, 将 yxy * x 赋值给 xx 继续操作, 问需要多少次, xx的位数大于等于 n。
题解: BFS 来解。

image.png

#include <iostream>
#include <cstring>
#include <set>
#include <map>
#include <vector>
#include <algorithm>
#include <queue>
using namespace std;

const int N = 10;

int bit[N];

#define PLL pair<long long, long long>
typedef long long ll;
ll nn = 1;
ll n, m;
map<ll, int> vist;

int  bfs(ll m){
     queue<PLL> q;
     q.push({m, 0});
     while(q.size()){
         auto t = q.front();
         q.pop();
         if(t.first == 0) return t.second;
         if(vist[t.first]) continue;
         vist[t.first] = t.second;
         ll x = t.first;
         int len = 0;
         while(x){
             bit[x%10] = 1;
             x/=10;
             len++;
         }
         // 大于等于 n 位,返回
         if(len >= n) return t.second;
         // i=1 不用计算了,剪枝
         for(int i=2; i<=9; i++){
             if(bit[i]){
                 q.push({t.first*i, t.second+1});
             }
         }
         //clear
         for(int i=2; i<=9; i++) bit[i] = 0;
     }
     return -1;
}
int main() {
     cin>>n>>m;
     // n位最小值
     for(int i=0; i<n; i++) nn*=10;
     cout<<bfs(m)<<endl;
     return 0;
}