zoukankan      html  css  js  c++  java
  • 「CodeForces Round #545 Div2」划水记

    真是上分场啊.

    机房的奆佬们一个个都上了红名,只有我还是蓝......


    (SV) 奆佬:本场比赛高分的关键是有没有早开 (F).

    然而我这个蒟蒻被 (B) 续了 (1space hr).


    A

    Descripition

    (n) 个数(0/1)中找到最长的子串使得0/1左右对半.

    Solution

    水题,模拟即可.

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    const int MAXN = 1e5 + 10;
    int n;
    int a[MAXN];
    int g[MAXN][2], f[MAXN][2];
    
    int main() {
    	scanf("%d", &n);
    	for (int i = 1; i <= n; ++i) scanf("%d", &a[i]), --a[i];
    	for (int i = 1; i <= n; ++i) {
    		if (a[i] == a[i - 1]) f[i][a[i]] = f[i - 1][a[i]] + 1;
    		else f[i][a[i]] = 1;
    	}
    	for (int i = n; i; --i) {
    		if (a[i] == a[i + 1]) g[i][a[i]] = g[i + 1][a[i]] + 1;
    		else g[i][a[i]] = 1;
    	}
    	int ans = 0;
    	for (int i = 1; i <= n; ++i) {
    		ans = max(max(min(f[i][0], g[i + 1][1]), min(f[i][1], g[i + 1][0])), ans);
    	}
    	printf("%d
    ", ans << 1);
    	return 0;
    }
    

    B

    Descripition

    给出 (a_1cdots a_n) , (b_1cdots b_n), 选出 (1le c_1lecdotsle c_{frac{n}{2}}le n),使得 (sum_{i=1}^{frac{n}{2}}a_{c_i}=sum_{iinleft[1,n ight]&i ot= c_jleft(jinleft[1,frac{n}{2} ight] ight)}b_i).

    输出任意一组 (c_i).

    Solution

    将每个有序对 (left(a_i,b_i ight)) 分成 (4) 类.

    然后分类讨论即可.

    具体过程详见代码.

    (刚开始一直过不了样例 (QAQ))

    Code

    #include <bits/stdc++.h>
    using namespace std;
    #define rep(i, l, r) for (int i = (l); i <= (r); ++i)
    #define per(i, r, l) for (int i = (r); i >= (l); --i)
    
    const int MAXN = 5005; 
    int n; 
    char s[2][MAXN]; 
    int A, B, C, D; 
    
    bool calc(int A, int B) {
    	return ~A&& A <= B; 
    }
    
    void print(int A, int B, int C, int D) {
    	for (int i = 1; A && i <= n; ++i) if (s[0][i] == '0' && s[1][i] == '0') printf("%d ", i), --A; 
    	for (int i = 1; B && i <= n; ++i) if (s[0][i] == '0' && s[1][i] == '1') printf("%d ", i), --B; 
    	for (int i = 1; C && i <= n; ++i) if (s[0][i] == '1' && s[1][i] == '0') printf("%d ", i), --C; 
    	for (int i = 1; D && i <= n; ++i) if (s[0][i] == '1' && s[1][i] == '1') printf("%d ", i), --D; 
    	puts("");
    	return;
    }
    
    inline void QAQ() {
    	puts("======QAQ======");
    	return;
    }
    
    int main() {
    	scanf("%d", &n); 
    	scanf("%s%s", s[0] + 1, s[1] + 1); 
    	rep(i, 1, n) {
    		if (s[0][i] == '0' && s[1][i] == '0') ++A; 
    		if (s[0][i] == '0' && s[1][i] == '1') ++B; 
    		if (s[0][i] == '1' && s[1][i] == '0') ++C; 
    		if (s[0][i] == '1' && s[1][i] == '1') ++D; 
    	}
    	rep(i, 0, n >> 1) rep(d1, 0, D) {
    		int d2 = D - d1; 
    		int c1 = i - d1, c2 = C - c1; 
    		int b2 = i - d2, b1 = B - b2; 
    		int a1 = n / 2 - b1 - c1 - d1, a2 = A - a1;
    		// QAQ();
    		if (calc(a1, A) && calc(a2, A) && calc(b1, B) && calc(b2, B) && calc(c1, C) && calc(c2, C) && calc(d1, D) && calc(d2, D) && a1+a2 == A && b1+b2 == B && c1+c2 == C && d1+d2 == D) {
    			print(a1, b1, c1, d1); 
    			// QAQ();
    			return 0; 
    		}
    	}
    	return puts("-1"), 0; 
    }
    

    C

    Descripition

    对于每个点,将其行和列所在元素离散化,这个点的答案为离散化后最大的数.

    Solution

    按题意做即可.

    反正 (C++) 自带离散化.

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    const int MAXN = 1e3 + 10, MAXM = 1e3 + 10;
    int n, m;
    int a[MAXN][MAXM], b[MAXN][MAXM], c[MAXN][MAXM], ans[MAXN][MAXM];
    int p[MAXN], q[MAXM];
    
    int main() {
    	scanf("%d%d", &n, &m);
    	for (int i = 1; i <= n; ++i)
    		for (int j = 1; j <= m; ++j)
    			scanf("%d", &a[i][j]), b[i][j] = a[i][j], c[j][i] = a[i][j];
    	for (int i = 1; i <= n; ++i) {
    		sort(b[i] + 1, b[i] + m + 1);
    		p[i] = unique(b[i] + 1, b[i] + m + 1) - b[i] - 1;
    	}
    	for (int i = 1; i <= m; ++i) {
    		sort(c[i] + 1, c[i] + n + 1);
    		q[i] = unique(c[i] + 1, c[i] + n + 1) - c[i] - 1;
    	}
    	for (int i = 1; i <= n; ++i)
    		for (int j = 1; j <= m; ++j) {
    			int x = lower_bound(b[i] + 1, b[i] + p[i] + 1, a[i][j]) - b[i];
    			int y = lower_bound(c[j] + 1, c[j] + q[j] + 1, a[i][j]) - c[j];
    			ans[i][j] = max(x, y) + max(p[i] - x, q[j] - y);
    		}
    	for (int i = 1; i <= n; ++i)
    		for (int j = 1; j <= m; ++j)
    			printf("%d%c", ans[i][j], " 
    "[j == m]);
    	return 0;
    }
    

    D

    Descripition

    给出 (01)(S), (T), 要求对 (S) 重新排列, 使得 (T)(S) 中出现的次数最大.

    Solution

    (KMP) 简单题.

    只要用一下 (next/fail​) 数组的性质就可以了.

    Code

    不要太在意变量名.

    #include <bits/stdc++.h>
    using namespace std;
    #define rep(i, l, r) for(int i=(l);i<=(r);++i)
    #define per(i, r, l) for(int i=(r);i>=(l);--i)
    
    const int MAXN = 500010;
    char S[MAXN], T[MAXN];
    int fuck[MAXN], n, m, j, A, B;
    
    inline void FUCK(int now) {
    	puts("FUCK");
    	puts("The Computer Is Stupid!!!");
    	printf("i=%d,j=%d
    ", now, j);
    	return;
    }
    
    int main() {
    	scanf(" %s %s", S + 1, T + 1);
    	n = strlen(S + 1), m = strlen(T + 1);
    	fuck[1] = 0, j = 0;
    	rep(i, 2, m) {
    		while (j && T[i] != T[j + 1]) j = fuck[j];
    		if (T[i] == T[j + 1]) ++j;
    		//FUCK(i);
    		fuck[i] = j;
    	}
    	rep(i, 1, n) {
    		if (S[i] == '0') ++A;
    		else if (S[i] == '1') ++B;
    	}
    	j = 0;
    	rep(i, 1, n) {
    		if (j == m) j = fuck[j]; ++j;
    		if ((T[j] == '0' && !A) || (T[j] == '1' && !B)) break;
    		if (T[j] == '0') --A;
    		else --B;
    		putchar(T[j]);
    	}
    	rep(i, 1, A) putchar('0');
    	rep(i, 1, B) putchar('1');
    	return 0;
    }
    

    E

    比赛的时候把题意看错了以为不可做.

    然后就没有做.

    赛后知道题意后发现可做.

    但既然比赛时没有做那赛后也就理所当然的不做了.

    F

    Descripition

    交互题.

    有一张图,一条链后是一个环,开始有 (10) 个棋子在链的起点.要求通过不超过 (3n)((n) 为点数)次操作,使得所有棋子均在环的起点.

    每次操作格式如下:

    (next) 后跟若干个数字,表示将这些棋子均向下一个节点移动一格.

    交互库会返回在同一个节点的棋子.

    Solution

    前几天 (Siyuan) 拉我做 「WC2015」未来程序.

    里面有一个点要用 (Floyd) 判圈.

    我就顺便学了一下.

    然后,就过了.(有史以来第一次考场过(F))


    每次让一个棋子走一格,另一个棋子走两格(这样一次会花费 (2) 次操作).

    当着两个棋子在同一个节点时(显然此时最多用了 (2n) 次操作),让所有棋子一起向前移动,最终所有棋子一定会到达同一个点(可以证明一定在 (n) 次操作内),则那个点就是环的起点.

    证明?

    好像很显然?

    Code

    #include <bits/stdc++.h>
    using namespace std;
    
    int n;
    char S[20];
    
    inline void ask1() {
    	puts("next 1");
    	puts("next 0 1");
    	return;
    }
    
    inline void ask2() {
    	puts("next 0 1 2 3 4 5 6 7 8 9");
    	return;
    }
    
    int main() {
    	while (2333) {
    		ask1();
    		fflush(stdout);
    		scanf("%d", &n);
    		for (int i = 1; i <= n; ++i) scanf(" %s", S);
    		scanf("%d", &n);
    		for (int i = 1; i <= n; ++i) scanf(" %s", S);
    		if (n == 2) break;
    	}
    	while (2333) {
    		ask2();
    		fflush(stdout);
    		scanf("%d", &n);
    		for (int i = 1; i <= n; ++i) scanf(" %s", S);
    		if (n == 1) break;
    	}
    	puts("done");
    	return 0;
    }
    

    后记

    好不容易苟上 (rank)(10).

    如果先开 (F) 应该还能更前面.

    看来我还是 ( exttt{too naive}).

  • 相关阅读:
    ubuntu 修改hostname
    hadoop "startdfs.sh" WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
    hadoop WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
    ubuntu replace system openjdk
    hadoop install start-dfs.sh 失败
    Centos610无桌面安装Docker-安装
    Centos610无桌面安装Docker-内核升级
    centos610无桌面安装libreoffice缺失字体
    centos610无桌面安装tomcat8
    Centos610无桌面安装VSFTP
  • 原文地址:https://www.cnblogs.com/realSpongeBob/p/CF1138.html
Copyright © 2011-2022 走看看