AtCoder Beginner Contest 190 Problem Solving Report

Topic link: abc190

A - Very Very Primitive Game

Topic

  • Takahashi and Aoki eat sweets, take turns eating sweets, and lose if the person in turn has no sweets.
  • a is the number of candies owned by T, b is the number of candies owned by A, c=0 means T eats first, c=1 means A eats first.
  • Output winner 
  • 0≤A,B≤100

Ideas

  • A to eat first means that T has eaten one, so you can let a+c, then unified T will eat candy first
  • If a>b then T wins, otherwise A wins

ac code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
    int a, b, c;
    cin >> a >> b >> c;
    a += c;
    if(a > b) puts("Takahashi");
    else puts("Aoki");
    return 0;
}

B - Magic 3

Topic

  • Magician fight monsters, n kinds of spells, each spell duration is ai, damage is bi
  • The shortest time a monster can withstand is s and the maximum damage is d
  • Ask the magician to successfully kill the monster
  • Range 1≤N≤100, 1≤ai≤1e9, 1≤bi≤1e9, 1≤s≤1e9, 1≤d≤1e9

Ideas

  • Find if there is ai<s and bi>d in all the spells
  • And operation is used here

ac code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
    int n, s, d, flag = 0;
    scanf("%d%d%d", &n, &s, &d);
    while(n --){
        int x, y;
        scanf("%d%d", &x, &y);
        flag |= (x < s && y > d);
    }
    if(flag) puts("Yes");
    else puts("No");
    return 0;
}

C - Bowls and Dishes

Topic

  • There are n kinds of dishes, m kinds of collocation a1, bi, k individual choice dishes,
  • Everyone has two choices: ci and di. After choosing, see how many collocations are satisfied
  • Ask how many matches are met at most
  • Range: 2≤N≤100, 1≤M≤100, 1≤Ai<Bi≤N, 1≤K≤16, 1≤Ci<Di≤N

Ideas

  • State compression
  • Because there are only 16 people at most, you can enumerate all situations in binary, 0 means choose the first dish, 1 means choose the second dish, and mark the vis array
  • Then traverse the collocation, if both exist, then cnt++, and finally update the maximum value of cnt

ac code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int a[105], b[105], c[105], d[105];
int vis[105];
int main(){
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= m; i ++){
        scanf("%d%d", &a[i], &b[i]);
    }
    int k; scanf("%d", &k);
    for(int i = 0; i < k; i ++){
        scanf("%d%d", &c[i], &d[i]);
    }
    int ans = 0;
    for(int t = 0; t < (1 << k); t ++){
        for(int i = 1; i <= n; i ++) vis[i] = 0;
        for(int i = 0; i < k; i ++){
            if((t >> i) & 1)  vis[d[i]] = 1;
            else vis[c[i]] = 1;
        }
        int cnt = 0;
        for(int i = 1; i <= m; i ++){
            if(vis[a[i]] + vis[b[i]] == 2) cnt ++;
        }
        ans = max(ans, cnt);
    }
    printf("%d\n", ans);
    return 0;
}

D - Staircase Sequences

Topic

  • Give you an n, and ask you how many arithmetic series can be formed, the tolerance d is 1, and the sum of the series is n?
  • 1≤N≤1e12

Ideas

  • The sum formula of the arithmetic sequence is S=n*a0+n*(n-1)*d/2
  • d=1, then S is related to the number of terms n and the first term a0, S is known, then use n to represent a0: a0=S/n-(n-1)/2 -> 2a0=2S/n+ 1-n
  • a0 is an integer, so 2S/n+1-n is an even number, and n is a factor of 2S.
  • Run O( \sqrt{n}) time to find the number of n that satisfy the condition.

ac code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int main(){
    ll n; cin >> n;
    int cnt = 0;
    n <<= 1;
    for(int i = 1; i <= sqrt(n); i ++){
        if(n % i == 0){
            if((n / i + 1 - i) % 2 == 0) cnt ++;
            ll d = n / i;
            if(i == d) continue;
            if((n / d + 1 - d) % 2 == 0) cnt ++;
        }
    }
    cout << cnt << endl;
    return 0;
}

F - Shift and Inversions

Topic

  • Give you n arrays from 0 to n-1, and then this array will rotate to the left by n-1
  • Ask you what is the reverse number pair of the array in this process
  • Inverse number pairs, the number of pairs <i, j> satisfying i<j, ai>aj
  • 2≤N≤3×1e5

Ideas

  • The initial reverse order of ans is done with a tree array or merge sort, here is a tree array,
  • Then, for example, {2, 0, 1, 3} this pair of circular shifts to the left becomes {0, 1, 3, 2}, that is, 2 is moved backward, then now, the number smaller than 2 is moved to the left, reverse order There are fewer pairs of a1, and numbers larger than 2 are also moved to the left, and there are more pairs of a2 in reverse order.
  • Since it is a full permutation, then the number a1 smaller than 2 has 2 pairs, and the number larger than 2 a2 has 4-1-2 pairs, which means that only ans-a1 + a2 is needed.
  • The maximum value of the reverse order pair is n*(n-1) / 2 so it will explode int, and long long needs to be opened

ac code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define lowbit(x) x & -x
const int maxn = 3e5 + 5;
int c[maxn], n;
void add(int x){
    for(int i = x; i <= n; i += lowbit(i))
        c[i] ++;
}
int query(int x){
    int ans = 0;
    for(int i = x; i > 0; i -= lowbit(i))
        ans += c[i];
    return ans;
}
int a[maxn];
int main(){
    ll ans = 0; cin >> n;
    for(int i = 1; i <= n; i ++){
        cin >> a[i]; a[i] ++;
        //由于树状数组不能加0,所以a[i]需要加1,那么下面的d1就要对应的+1, d2要对应的-1
        add(a[i]);
        //query求的是小于等于a[i]的数的个数,i是现在有的个数
        //那么现在要求的是逆序对,也就是要求前面比他大的数的个数,那么就是i-query
        ans += i - query(a[i]); 
    }
    int d1 = 0, d2 = 0;
    for(int i = 1; i <= n; i ++){
        cout << ans << endl;
        d1 = n - a[i], d2 = a[i] - 1;
        ans += d1 - d2;
    }
    return 0;
}

 

Guess you like

Origin blog.csdn.net/weixin_43911947/article/details/113448497
Recommended