• Codeforces Edu Round 60 A-E


    A. Best Subsegment

    显然,选择数列中的最大值当做区间(长度为(1))。只要尝试最大值这个区间是否能扩展(左右两边值是否跟它一样就行了)

    #include <cstdio>
    #include <iostream>
    #include <cmath> 
    using namespace std;
    const int N = 100010;
    int n, a[N], val = -1, res = -1; 
    int main(){
    	scanf("%d", &n);
    	for(int i = 1; i <= n; i++) {
    		scanf("%d", a + i);
    		val = max(val, a[i]);
    	}
    	int len = 0;
    	for(int i = 1; i <= n; i++){
    		if(a[i] == val) len ++;
    		else len = 0;
    		res = max(res, len);
    	}
    	printf("%d
    ", res);
    	return 0;
    }
    
    

    B. Emotes

    贪心。让总和最大,考虑可以尽量选最大的,每次选(k)次,然后选一个第二大的,接着选(k)次最大的...就这样轮替。这个过程可以用取余来快速完成,每一轮的次数是(k + 1)

    #include <cstdio>
    #include <iostream>
    #include <cmath> 
    using namespace std;
    typedef long long LL;
    const int N = 200010;
    int n, m, k, a[N], max1 = -1, max2 = -1;
    LL res = 0;
    int main(){
    	scanf("%d%d%d", &n, &m, &k);
    	for(int i = 1; i <= n; i++) {
    		scanf("%d", a + i);
    		if(a[i] > max1){
    			max2 = max1;
    			max1 = a[i];
    		}else if(a[i] > max2){
    			max2 = a[i];
    		}
    	}
    	int num = m / (k + 1), ot = m % (k + 1);
    	printf("%lld
    ", (LL)num * k * max1 + (LL)num * max2 + (LL)ot * max1);
    	 
    	
    	return 0;
    }
    

    C. Magic Ship

    二分答案。容易看出,时刻符合单调性。若(d)天能到,那么(d + 1)也能到。因为可以保持跟风相反的方向就可以保持不动,晚一个时刻在到。如果设置(check)函数,我们先把这些天风走的走完,再看现在的曼哈顿距离是否够天数走完的即可。对于二分答案的上界,可以设置为(1e14),最坏情况所有(n)次只有一次是顺方向,剩下都是逆方向,那么每(n)次只能动(2)步,结合最大需求曼哈顿是(1e9 * 2 = 2e9),所以最高时间就是(n * 2e9 / 2 = 100000 * 2e9 / 2 = 1e14)

    #include <cstdio>
    #include <iostream>
    #include <cstring>
    #include <cmath>
    using namespace std;
    const int N = 100010; 
    typedef long long LL;
    int x, y, x2, y2, n, sum[N][2];
    char s[N]; 
    //检查x时间是否可行。 
    bool check(LL d){
    	LL nx = x, ny = y;
    	nx += (d / n) * sum[n][0] + sum[d % n][0];
    	ny += (d / n) * sum[n][1] + sum[d % n][1];
    	return abs(x2 - nx) + abs(y2 - ny) <= d;
    }
    int main(){
    	scanf("%d%d%d%d%d%s", &x, &y, &x2, &y2, &n, s + 1);
    	for(int i = 1; i <= n; i++){
    		sum[i][1] += sum[i - 1][1] + (s[i] == 'U');
    		sum[i][1] -= (s[i] == 'D');
    		sum[i][0] -= (s[i] == 'L');
    		sum[i][0] += sum[i - 1][0] + (s[i] == 'R');
    	}
    	if(!check(1e14)) puts("-1");
    	else{
    		LL l = 1, r = 1e14;
    		while(l < r){
    			LL mid = (l + r) >> 1;
    			if(check(mid))r = mid;
    			else l = mid + 1;
    		}	
    		printf("%lld
    ", r);
    	}
    	
    	
    	return 0;
    }
    

    D. Magic Gems

    考虑(dp),每次有两个决策,一个是放(m)个普通宝石,或者放一个(1)个魔法宝石。

    (f[i])为填i个区间的方案数,状态转移方程(f[i] = f[i - 1] + f[i - m])

    初始化(f[1] = f[2] = ... = f[m - 2] = f[m - 1] = 1)

    然后我就不会优化了...只能看题解,发现要用矩阵快速幂 or 杜教优化,但是本蒟蒻两个都不会,所以这个坑以后再填...

    E. Decypher the String

    我自闭了。既然可以二进制确定一个范围,那么我们尝试(26)进制系列,因为字母各不相同可以确定转换位置。由于(26 ^ 2 < 10000 < 26 ^ 3),范围之内可以解决。

    询问三个分别如下:

    1. (aaaa(26 * 26)bbbb(26 * 26)...zzzz(26 * 26))
    2. (aaaa(26)bbbb(26)...zzzz(26)aaaa...)
    3. (abcdefghijklmn...xyzabcd...xyz...)

    这样每一步可以将答案缩小至原来的(frac{1}{26}),在范围可以解决问题。

    为了方便找到交集,我们用(bitset)即可。

    PS:这毒瘤输入输出...这个它提示我输入格式不正确。

    #include <cstdio>
    #include <iostream>
    #include <bitset>
    #include <cstring>
    using namespace std;
    const int N = 10000;
    char str[N], s[3][N], ans[N];
    bitset<N> a[3][26]; 
    int n;
    int main(){
    	scanf("%s", str);
    	n = strlen(str);
    	for(int i = 0; i < n; i++)
    		for(int j = 0, t = i; j < 3; j++)
    			s[j][i] = t % 26 + 'a', t /= 26;
    		
    	for(int i = 0; i < 3; i++){
    		printf("? %s
    ", s[i]), fflush(stdout), scanf("%d", s[i]);
    	}
    	
    	for(int i = 0; i < 3; i++)
    		for(int j = 0; j < n; j++)
    			a[i][s[i][j] - 'a'].set(i);
    	
    	for(int i = 0; i < n; i++){
    		bitset<N> u;
    		for(int j = 0, t = i; j < 3; j++)
    			u &= a[j][t % 26], t /= 26;
    		for(int j = 0; j < n; j++)
    			if(u[j]) { ans[i] = str[j]; break; }
    	}
    	printf("! %s
    ", ans);
    	return 0;
    }
    
    

    然后我改成单个的就对了,wtf????

    #include <cstdio>
    #include <iostream>
    #include <bitset>
    #include <cstring>
    using namespace std;
    const int N = 10005;
    char str[N], s1[N], s2[N], s3[N], ans[N];
    bitset<N> a[3][26], now; 
    int n;
    int main(){
    	scanf("%s", str);
    	n = strlen(str);
    	 for (int i = 0; i< n; ++i) {
            int t = i;
            s1[i] = 'a' + t % 26; t /= 26;
            s2[i] = 'a' + t % 26; t /= 26;
            s3[i] = 'a' + t % 26; t /= 26;
        }	
    	printf("? "); puts(s1); fflush(stdout); scanf("%s", s1);
        printf("? "); puts(s2); fflush(stdout); scanf("%s", s2);
        printf("? "); puts(s3); fflush(stdout); scanf("%s", s3);
    	
    	for (int i = 0; i < n; ++i) a[0][s1[i] - 'a'].set(i);
        for (int i = 0; i < n; ++i) a[1][s2[i] - 'a'].set(i);
        for (int i = 0; i < n; ++i) a[2][s3[i] - 'a'].set(i);
        
    	
    	for (int i = 0; i < n; ++i) {
            int t = i;
            now = a[0][t % 26]; t /= 26;
            now &= a[1][t % 26]; t /= 26;
            now &= a[2][t % 26]; t /= 26;
            for (int j = 0; j < n; ++j) 
                if (now[j]) { ans[i] = str[j]; break; }
        }
    	printf("! %s
    ", ans);
    	return 0;
    }
    
    

    原因应该是字符数组二维读入上和输出没有好的规定......

  • 相关阅读:
    sqlilab less19-less22
    sqlilab less11-less18
    逆向——序列号相关总结
    xctf攻防世界——crackme writeup
    ESP定律脱壳——NsPack3.x脱壳
    避免全局变量漫天飞
    C语言实现队列
    STM32中的C语言知识点
    超时事件时间戳
    STM32-电源控制、低功耗模式
  • 原文地址:https://www.cnblogs.com/dmoransky/p/11296807.html
Copyright © 2020-2023  润新知