• 1012考试


    1012考试总结

    T1

    ​ 物理题。。。。。

    T2

    ​ 题目大意:

    ​ 给你(n)个01字符串,这个字符串可以重复无数遍:(010 : 010010)(10001 : 100011000110001),就像这样。问最多会有多少位至少两个串相等。

    ​ 比如:

    5
    001
    1000
    0100
    010
    100
    输出为:4,因为第三个串和第四个串前4位相同
    

    ​ 考虑分治的做法,我们枚举位数,假设当前枚举到了第(x)为,我们把这一位为0的分到一起,把这一位为1的分到一起,然后递归为0的和为1的下一位,直到不能继续递归为止。

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N = 2e4 + 5;
    int n, ans, cnt1, cnt2;
    int sta1[N], sta2[N];
    string ch[N];
    
    int solve(int now, int *a, int *b, int cnt1, int cnt2) {
        if(!cnt1 && !cnt2) return 0;
        if(cnt1 + cnt2 == 1) return 0;
        int sa[N], sb[N];
        int x = 0, y = 0, res;
        for(int i = 1;i <= cnt1; i++) 
            if(ch[a[i]][now] == '0') sa[++ x] = a[i];
            else sb[++ y] = a[i];
        res = solve(now + 1, sa, sb, x, y) + 1;
        x = 0, y = 0;
        for(int i = 1;i <= cnt2; i++)
            if(ch[b[i]][now] == '0') sa[++ x] = b[i];
            else sb[++ y] = b[i];
        res = max(res, solve(now + 1, sa, sb, x, y) + 1);
        return res;
    }
    
    int main() {
    
        scanf("%d", &n);
        for(int i = 1;i <= n; i++) {
            cin >> ch[i]; 
            string a = ch[i]; int len = a.length();
            while(ch[i].length() + len <= 1000) ch[i] += a;
            if(ch[i][0] == '0') sta1[++ cnt1] = i;
            else sta2[++ cnt2] = i;
        }
        printf("%d", solve(1, sta1, sta2, cnt1, cnt2) - 1);
        
        fclose(stdin); fclose(stdout);
        return 0;
    }
    

    T3

    ​ 题目大意:

    ​ 给你一段序列(保证每个数两两不同),有两种操作:

    ​ 第一种:询问一个数(x)前面最小的数是多少,如果没有输出-1;

    ​ 第二种:将一个数(x)移动到队伍末尾,原来的位置空着。

    ​ 最后输出一个数,表示得到最后的序列后,每次移动一个数,向前向后都可以,为最少几次可以使中间没有空缺,前面和后面可以没有人,只要是长度为(n)的连续的一段数就行。

    (n, m <= 100000, 0 <= a[i] <= 100000000)

    ​ 考场山第一问做出来了,第二问没想出来咋做,好可惜。

    ​ 首先离散化。

    ​ 开一颗线段树维护区间最小值,注意要开(2e5 * 4),以为最多有(m)次移动操作,所以原序列最多会变成(2 * n)那么长。询问操作直接查询区间最小值,移动操作就是将原位置的数删去,在队尾位置加上这个数。

    ​ 对于第二问,我们把位置上有人的记为1,把位置上没人的记为0,我们维护一个长度为(n)的滑动窗口,看看里边有多少个0,取最小值就是第二问答案。(Cao竟然没想出来)

    #include <bits/stdc++.h>
    
    #define ls(o) (o << 1)
    #define rs(o) (o << 1 | 1)
    #define mid ((l + r) >> 1)
    
    using namespace std;
    
    inline long long read() {
        long long s = 0, f = 1; char ch;
        while(!isdigit(ch = getchar())) (ch == '-') && (f = -f);
        for(s = ch ^ 48;isdigit(ch = getchar()); s = (s << 1) + (s << 3) + (ch ^ 48));
        return s * f;
    }
    
    const int N = 2e5 + 5, inf = 1e9;
    int n, m, x, to, mo, ans, len, res;
    char ch; 
    int a[N], b[N], y[N], q[N], pos[N];
    struct edge { int Min; } t[N << 2];
    
    void up(int o) {
        t[o].Min = min(t[ls(o)].Min, t[rs(o)].Min);
    }
    
    void build(int o, int l, int r) {
        if(l == r) { if(l <= n) t[o].Min = a[l]; else t[o].Min = inf; return ; }
        build(ls(o), l, mid); build(rs(o), mid + 1, r);
        up(o);
    }
    
    int query(int o, int l, int r, int x, int y) {
        if(x <= l && y >= r) { return t[o].Min; }
        int tmp = inf;
        if(x <= mid) tmp = min(tmp, query(ls(o), l, mid, x, y));
        if(y > mid) tmp = min(tmp, query(rs(o), mid + 1, r, x, y));
        return tmp;
    }
    
    void change(int o, int l, int r, int x, int val) {
        if(l == r) { a[l] = val; t[o].Min = val; return ; }
        if(x <= mid) change(ls(o), l, mid, x, val);
        if(x > mid) change(rs(o), mid + 1, r, x, val);
        up(o);
    }
    
    int main() {
    
        n = read(); m = read();
        for(int i = 1;i <= n; i++) a[i] = b[i] = read();
        sort(b + 1, b + n + 1);
        int cnt = unique(b + 1, b + n + 1) - b - 1;
        for(int i = 1;i <= n; i++) {
            int tmp = a[i]; a[i] = lower_bound(b + 1, b + cnt + 1, a[i]) - b, y[a[i]] = tmp, pos[a[i]] = i;
        }
        len = 2 * max(n, m);
        build(1, 1, len); to = 1; mo = n;
        for(int i = 1;i <= m; i++) {
            cin >> ch; x = read();
            int li = lower_bound(b + 1, b + cnt + 1, x) - b;
            if(ch == 'A') { 
                if(pos[li] == 1) { printf("-1
    "); continue; }
                int tmp = query(1, 1, len, 1, pos[li] - 1);
                if(tmp == inf) printf("-1
    ");
                else printf("%d
    ", y[tmp]);
            }
            if(ch == 'M') {
                change(1, 1, len, pos[li], inf);
                mo ++; pos[li] = mo;
                change(1, 1, len, mo, li);
            }
        }
        for(int i = 1;i <= n; i++) if(a[i] == inf) res ++;
        ans = res;
        for(int i = n + 1;i <= mo; i++) {
            if(a[i - n] == inf) res --;
            if(a[i] == inf) res ++;
            ans = min(ans, res);
        }
        printf("%d", ans);
    
        fclose(stdin); fclose(stdout);
        return 0;
    }
    
  • 相关阅读:
    python面试题目【转1】
    让python和C/C++联姻【转】
    python面试模拟真题讲解
    JavaScript真的要一统江湖了
    WebApp
    Linux服务器之SSH
    web服务之http
    SNMP简单网络管理协议
    Storm,Spark和Samza
    Stream computing
  • 原文地址:https://www.cnblogs.com/czhui666/p/13806570.html
Copyright © 2020-2023  润新知