zoukankan      html  css  js  c++  java
  • Ozon Tech Challenge 2020 (Div.1 + Div.2)

    传送门

    A. Kuroni and the Gifts

    签到。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/3 22:36:21
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1e5 + 5;
     
    int n;
    int a[N], b[N];
     
    void run() {
        cin >> n;
        for(int i = 1; i <= n; i++) cin >> a[i];
        for(int i = 1; i <= n; i++) cin >> b[i];
        sort(a + 1, a + n + 1), sort(b + 1, b + n + 1);
        for(int i = 1; i <= n; i++) cout << a[i] << " 
    "[i == n];
        for(int i = 1; i <= n; i++) cout << b[i] << " 
    "[i == n];
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        int T; cin >> T;
        while(T--) run();
        return 0;
    }
    

    B. Kuroni and Simple Strings

    贪心即可。
    最后一定会删除左边(x)('('),右边(x)(')'),假设删除完过后的串依旧不符合条件,那么继续删左边(y)个、右边(y)个。
    最后归纳一下,那么直接看左右两边最多删多少个就行。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/3 22:44:47
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1000 + 5;
     
    char s[N];
    int sta[N], top;
     
    void run() {
        cin >> (s + 1);
        int n = strlen(s + 1);
        int cnt = 0;
        vector <int> v;
        int l = 0, r = n + 1;
        int c1 = 0, c2 = 0;
        while(l + 1 < r) {
            while(l + 1 < r && c1 == c2) {
                ++l;
                if(s[l] == '(') {
                    ++c1; 
                    v.push_back(l);
                }
            }
            while(l + 1 < r && c1 == c2 + 1) {
                --r;
                if(s[r] == ')') {
                    ++c2;
                    v.push_back(r);   
                }
            }
        }
        if(sz(v) & 1) v.pop_back();
        if(sz(v) == 0) {
            cout << 0 << '
    ';   
        } else {
            cout << 1 << '
    ';
            cout << sz(v) << '
    ';
            sort(all(v));
            for(auto it : v) cout << it << ' ';
            cout << '
    ';   
        }
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    C. Kuroni and Impossible Calculation

    题意:
    给出(a_{1,2,cdots,n}),求(displaystyle prod_{1leq i<jleq n}|a_i-a_j| \% m)
    其中(nleq 2cdot 10^5,mleq 1000)

    思路:
    抽屉原理。
    (a_i)按模(m)进行分类,如果存在(i,j),满足(a_iequiv a_j(mod m)),那么必然(|a_i-a_j|\% m=0),最后答案就为(0)
    由抽屉原理,当(n>m)时,会出现上述情况,答案为(0)
    (nleq m)时,暴力计算即可。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/3 23:20:27
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 2e5 + 5;
     
    int n, m;
    int a[N];
     
    void run() {
        vector <int> mod(m);
        for(int i = 1; i <= n; i++) {
            cin >> a[i];
            ++mod[a[i] % m];
        }
        for(int i = 0; i < m; i++) {
            if(mod[i] > 1) {
                cout << 0 << '
    ';
                return;
            }   
        }
        int ans = 1;
        for(int i = 1; i <= n; i++) {
            for(int j = i + 1; j <= n; j++) {
                ans = 1ll * ans * abs(a[i] - a[j]) % m;
            }   
        }
        cout << ans << '
    ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        while(cin >> n >> m) run();
        return 0;
    }
    

    D. Kuroni and the Celebration

    题意:
    交互题。
    现在有一颗(n,nleq 5000)个结点的有根树,但你并不知道哪个为根。
    之后你可以通过不超过(lfloorfrac{n}{2} floor)次询问,每次询问两个点((u,v)),回答会给出(lca(u,v))
    最后要确定树根。

    思路:
    不妨以(1)结点作为根建出一颗有根树。

    • 我们从(1)号结点开始,对其儿子两两进行询问,若给出的答案为两儿子之一,那么根结点必然在这个儿子的子树中。那么到儿子的子树中继续递归进行操作即可。
    • 最后可能会剩下一个单独的儿子,我的策略就是(dfs)到该子树中随便的一个叶子,然后询问根节点和该叶子结点。如果回答为两个之一,那么便确定了树根;否则就到回答给出的结点继续递归操作。

    以上操作即可保证每个点至多出现在一个询问中,满足限制条件。
    注意一个细节就是,已经询问过的点不用再次询问。
    我代码写的时候有点复杂,在(dfs)找叶子结点的时候就把点给标记了,其实意思是一个意思。。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/3 23:44:14
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 1000 + 5;
    
    int n;
    vector <int> G[N], sons[N];
    bool chk[N];
    int now;
    
    void dfs(int u, int fa) {
        for(auto v : G[u]) if(v != fa) {
            dfs(v, u);
            sons[u].push_back(v);
        }   
    }
    
    int query(int u, int v) {
        cout << '?' << ' ' << u << ' ' << v << endl;
        int z; cin >> z;
        return z;   
    }
    
    int get(int u) {
        chk[u] = true;
        int SZ = sz(sons[u]);
        for(auto it : sons[u]) if(chk[it]) --SZ;
        if(SZ == 0) return u;
        for(auto it : sons[u]) if(!chk[it]) {
            return get(it);   
        }
    }
    
    void gao(int u) {
    	now = u;
        int SZ = sz(sons[u]);
        for(auto it : sons[u]) if(chk[it]) --SZ;
        if(SZ == 0) {
            return;
        } else if(SZ == 1) {
            for(auto it : sons[u]) if(!chk[it]) {
                int to = get(it);
                int z = query(u, to);
                now = z; 
                if(z == to || z == u) return;   
                gao(now);
                return;   
            }
        } else {
            vector <int> v;
            for(auto it : sons[u]) if(!chk[it]) v.push_back(it);
            for(int i = 0; i < sz(v); i += 2) {
                if(i + 1 < sz(v)) {
                    int z = query(v[i], v[i + 1]);
                    if(z == v[i] || z == v[i + 1]) {
                        now = z;
                        gao(now);
                        return;
                    }
                } else {
                    int to = get(v[i]);
                    int z = query(u, to);
                    now = z;
                    if(z == to || z == u) return;
                    gao(now);
                    return;
                }
            }
        }
    }
    
    void run() {
        cin >> n;
        for(int i = 1; i < n; i++) {
            int u, v; cin >> u >> v;
            G[u].push_back(v);
            G[v].push_back(u);
        }
        dfs(1, 0);
        gao(1);
        cout << "!" << ' ' << now << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    E. Kuroni and the Score Distribution

    构造的话直接贪心构造。
    (123456...),最后补差就行。
    因为从(3)开始贡献依次为(1,1,2,2,3,3,4,4,cdots)
    若最终没有补够(n)项,那么就填大的数并且有足够大的间隔即可。

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/4 0:38:46
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 5000 + 5;
     
    int n, m;
     
    void run() {
        cin >> n >> m;
        if(n == 1) {
            if(m == 0) cout << 1 << '
    ';
            else cout << -1 << '
    ';   
            return;
        }
        vector <int> a;
        a.push_back(1);
        a.push_back(2);
        int now = 1, cnt = 0;
        int t = 0, p = 3;
        while(t < m) {
            if(t + now > m) {
                int r = m - t;
                --p;
                for(int i = p + 1;; i++) {
                    int L = i - p, R = p;
                    if((R - L + 1) / 2 == r) {
                        a.push_back(i);
                        t += r;
                        break;
                    }
                }
            } else {
                a.push_back(p++);
                t += now;
                if(++cnt == 2) {
                    ++now, cnt = 0;   
                }
            }
        }
        if(sz(a) > n) {
            cout << -1 << '
    ';
            return;   
        }
        int s = 1e9;
        while(sz(a) < n) {
            a.push_back(s);
            s -= 50000;   
        }
        sort(all(a));
        for(auto it : a) cout << it << ' ';
    }
     
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        run();
        return 0;
    }
    

    F. Kuroni and the Punishment

    题意:
    给出(a_{1,2,cdots,n},nleq 10^5,a_ileq 10^{12})
    现在可以执行任意次操作:

    • 选择一个数(a_i),对其加一或者减一,不能出现(0)或负数。

    现在问最少需要多少次操作,使得(gcd(a_1,a_2,cdots,a_n)>1)

    思路:
    考虑最终(gcd=2)的情况,显然这跟(a_i)的奇偶性有关,那么我们得出了答案的上界(n)
    据此上界我们可以推出,若某些位置执行的操作次数(geq 2),那么这些位置不超过(frac{n}{2})。也就是说我们有不少于一半的位置最终只执行了(0)次或(1)次操作。
    那么我们随机选一个位置,对其执行不超过(1)次操作,之后枚举(gcd),显然我们只用枚举其质因子即可。
    最终的复杂度为(O(随机次数*(n+logn)))
    我们随机(20)次即可,那么一次都没随机到的几率不超过(frac{1}{2^{20}}),几乎可以忽略。
    代码如下:

    Code
    /*
     * Author:  heyuhhh
     * Created Time:  2020/3/4 10:56:42
     */
    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <vector>
    #include <cmath>
    #include <set>
    #include <map>
    #include <queue>
    #include <iomanip>
    #include <assert.h>
    #include <random>
    #define MP make_pair
    #define fi first
    #define se second
    #define pb push_back
    #define sz(x) (int)(x).size()
    #define all(x) (x).begin(), (x).end()
    #define INF 0x3f3f3f3f3f3f3f3f
    #define Local
    #ifdef Local
      #define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
      void err() { std::cout << '
    '; }
      template<typename T, typename...Args>
      void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
      template <template<typename...> class T, typename t, typename... A> 
      void err(const T <t> &arg, const A&... args) {
      for (auto &v : arg) std::cout << v << ' '; err(args...); }
    #else
      #define dbg(...)
    #endif
    using namespace std;
    typedef long long ll;
    typedef pair<int, int> pii;
    //head
    const int N = 2e5 + 5, MAX = 2e6 + 5;
    
    int n;
    ll a[N];
    
    mt19937 rnd(time(NULL));
    
    int primes[MAX], tot;
    bool chk[MAX];
    
    void init() {
        for(int i = 2; i < MAX; i++) {
            if(!chk[i]) primes[++tot] = i;
            for(ll j = 1ll * i * i; j < MAX; j += i) chk[j] = true;
        }   
    }
    
    ll gao(ll x) {
        if(x == 1) return INF;
        auto solve = [&] (ll pri) {
            ll res = 0;
            for(int i = 1; i <= n; i++) {
                if(a[i] < pri) res += pri - a[i];
                else res += min(a[i] % pri, pri - a[i] % pri);
            }   
            return res;       
        };
        ll ans = INF;
        for(int i = 1; i <= tot; i++) {
            if(primes[i] > x) break;
            if(x % primes[i] == 0) {
                ans = min(ans, solve(primes[i]));
                while(x % primes[i] == 0) x /= primes[i];        
            }
        }
        if(x > 1) ans = min(ans, solve(x));
        return ans;
    }
    
    void run() {
        cin >> n;
        for(int i = 1; i <= n; i++) cin >> a[i];
        ll ans = n;
        for(int i = 1; i <= 20; i++) {
            int id = rnd() % n + 1;
            for(int j = -1; j <= 1; j++) ans = min(ans, gao(a[id] + j));
        }
        cout << ans << '
    ';
    }
    
    int main() {
        ios::sync_with_stdio(false);
        cin.tie(0); cout.tie(0);
        cout << fixed << setprecision(20);
        init();
        run();
        return 0;
    }
    
  • 相关阅读:
    自定义组件要加@click方法
    绑定样式
    647. Palindromic Substrings
    215. Kth Largest Element in an Array
    448. Find All Numbers Disappeared in an Array
    287. Find the Duplicate Number
    283. Move Zeroes
    234. Palindrome Linked List
    202. Happy Number
    217. Contains Duplicate
  • 原文地址:https://www.cnblogs.com/heyuhhh/p/12408656.html
Copyright © 2011-2022 走看看