zoukankan      html  css  js  c++  java
  • Codeforces Round #620 (Div. 2) 简要题解

    Codeforces Round #620 (Div. 2)

    A:a + b整除y - x的时候可以跳到一起。

    int main() {
    	int t; scanf("%d", &t);
    	while(t --) {
    		int x, y, a, b;
    		scanf("%d%d%d%d", &x, &y, &a, &b); y -= x;
    		printf("%d
    ", y % (a + b) == 0 ? (y / (a + b)) : -1);
    	}
    	return 0;
    } 
    

    B:因为串长都一样所以好做。如果是本身是回文串,出现了奇数次就拿一个放中间,其他放两边。如果不是回文串但原串和反串各出现x, y次,两边接上min(x, y)对。

    int n, m, f[N], g[N];
    char s[110][110];
    bool same(int u, int v) {
    	for(int i = 1; i <= m; i ++)
    		if(s[u][i] != s[v][i]) return 0;
    	return 1; 
    }
    bool rev(int u, int v) {
    	for(int i = 1; i <= m; i ++)
    		if(s[u][i] != s[v][m - i + 1]) return 0;
    	return 1; 
    }
    void print(int u) {
    	printf("%s", s[u] + 1);
    }
    void pf(int u) {
    	for(int i = m; i >= 1; i --) putchar(s[u][i]);
    }
    int main() {
    	scanf("%d%d", &n, &m);
    	for(int i = 1; i <= n; i ++) {
    		scanf("%s", s[i] + 1);
    		bool t = 0;
    		for(int j = 1; j < i; j ++) {
    			if(same(i, j)) { f[j] ++; t = 1; break ; }
    			if(rev(i, j)) { g[j] ++; t = 1; break ; }
    		}
    		if(t) { i --; n --; continue ; }
    		f[i] = 1;
    	}
    	int len = 0, mid = 0, midx;
    	vector<int> ans;
    	for(int i = 1; i <= n; i ++) {
    		if(rev(i, i)) {
    			len += 2 * m * (f[i] / 2);
    			for(int j = f[i] / 2; j >= 1; j --)
    				ans.push_back(i);
    			if(f[i] % 2 == 1) { mid = 1; midx = i; }
    		} else {
    			for(int j = min(f[i], g[i]); j >= 1; j --)
    				ans.push_back(i);
    			len += 2 * m * min(f[i], g[i]); 
    		}
    	}
    	printf("%d
    ", len + mid * m);
    	for(int i = 0; i < (int) ans.size(); i ++) print(ans[i]);
    	if(mid) print(midx);
    	for(int i = (int) ans.size() - 1; i >= 0; i --) pf(ans[i]);
    	return 0;
    } 
    

    C:每次维护一个区间,表示这个区间里的温度都可以达到。如果发现上一轮的区间转移不到当前要求区间就NO。

    struct Node { int t, l, r; } a[N];
    int q, n, m;
    int main() {
    	scanf("%d", &q);
    	while(q --) {
    		scanf("%d%d", &n, &m);
    		for(int i = 1; i <= n; i ++)
    			scanf("%d%d%d", &a[i].t, &a[i].l, &a[i].r);
    		int ql = m, qr = m; bool fail = 0;
    		for(int i = 1; i <= n; i ++) {
    			int nl = a[i].l, nr = a[i].r, dt = a[i].t - a[i - 1].t;
    			if(nr < ql - dt || nl > qr + dt) { fail = 1; break ; }
    			ql -= dt; qr += dt; ql = max(ql, nl); qr = min(qr, nr);
    		}
    		puts(fail ? "NO" : "YES");
    	}
    	return 0;
    } 
    

    D:

    LIS最短:容易知道答案>= max(连续'<'长度) + 1.可以构造出恰等于的情况:每次分一个连续段从最大的一段取。

    LIS最长:容易知道答案<= max('<'个数 + 1, '>'段个数)。容易知道前者更大,于是构造恰等于'<'个数 + 1的排列:维护l, r初始为1,p[1] = 1。若是小于就分配++ r否则分配-- l,最后在把值域换成[1, n],显然正确。当然也可以仿照LIS最短做。

    int n, x[N], ans[N];
    char s[N];
    int main() {
    	int t; scanf("%d", &t);
    	while(t --) {
    		scanf("%d%s", &n, s + 2);
    		int l = 1, r = n;
    		for(int i = 2; i <= n; ) {
    			int j = i;
    			for(; j < n && s[j + 1] == s[i]; j ++) ;
    			if(s[i] == '<') {
    				for(int k = j; k >= i; k --) x[k] = r --;
    				if(i == 2) x[1] = r --;
    				else {
    					int t = x[i - 1];
    					for(int k = i; k <= j; k ++) x[k - 1] = x[k];
    					x[j] = t;
    				}
    			} else {
    				if(i == 2) x[1] = r --;
    				for(int k = i; k <= j; k ++) x[k] = r --;
    			}
    			i = j + 1; 
    		}
    		for(int i = 1; i <= n; i ++) printf("%d%c", x[i], " 
    "[i == n]);
    		
    		x[1] = 1; l = 1, r = 1; int mp = 1;
    		for(int i = 2; i <= n; i ++) {
    			if(s[i] == '<') x[i] = ++ r;
    			else x[i] = -- l;
    			mp = min(mp, x[i]);
    		}
    		if(mp != 1) { for(int i = 1; i <= n; i ++) x[i] -= mp - 1; }
    		for(int i = 1; i <= n; i ++) printf("%d%c", x[i], " 
    "[i == n]);
    	}
    	return 0;
    } 
    

    E:我们只需求出a->b,a->x->y->b, a->y->x->b这三条路径是不是 + 2N = k。

    bool ok(int x, int y) {
    	return x <= y && (y - x) % 2 == 0;
    }
    int main() {
    	scanf("%d", &n);
    	for(int i = 1; i < n; i ++) {
    		int u, v;
    		scanf("%d%d", &u, &v);
    		G[u].pb(v); G[v].pb(u);
    	}
    	dfs(1, 0);
    	scanf("%d", &q);
    	for(int i = 1; i <= q; i ++) {
    		int x, y, a, b, k;
    		scanf("%d%d%d%d%d", &x, &y, &a, &b, &k);
    		int d = dis(a, b); bool tag = 0;
    		if(ok(d, k)) tag = 1;
    		if(ok(dis(a, x) + dis(b, y) + 1, k)) tag = 1;
    		if(ok(dis(a, y) + dis(b, x) + 1, k)) tag = 1;
    		puts(tag ? "YES" : "NO");
    	}
    	return 0;
    } 
    

    F:dp[i][j]表示前i行的答案,其中第i行选[i, j]。单调队列转移

    const int N = 62, M = 4e4 + 10;
    int n, m, k, a[N][M], s[N][M], dp[N][M];
    int calc(int x, int y) {
    	return s[x][y + k - 1] - s[x][y - 1] + s[x + 1][y + k - 1] - s[x + 1][y - 1];
    }
    int main() {
    	scanf("%d%d%d", &n, &m, &k);
    	for(int i = 1; i <= n; i ++) {
    		for(int j = 1; j <= m; j ++) scanf("%d", &a[i][j]);
    		for(int j = 1; j <= m + k; j ++) s[i][j] = s[i][j - 1] + a[i][j];
    	}
    	for(int i = 1; i <= m; i ++) dp[1][i] = calc(1, i);
    	static int q[M], l, r;
    	for(int i = 2; i <= n; i ++) {
    		l = r = 0; int Max = -2e9;
    		for(int j = 1; j <= m; j ++) {
    			if(j - k >= 1) Max = max(Max, dp[i - 1][j - k]);
    			while(l < r && dp[i - 1][q[r - 1]] - s[i][q[r - 1] + k - 1] <= dp[i - 1][j] - s[i][j + k - 1]) r --;
    			q[r ++] = j;
    			while(l < r && q[l] + k - 1 < j) l ++;
    			dp[i][j] = calc(i, j) + max(Max, dp[i - 1][q[l]] - s[i][q[l] + k - 1] + s[i][j - 1]);
    		}
    		l = r = 0; Max = -2e9;
    		for(int j = m; j >= 1; j --) {
    			if(j + k <= m) Max = max(Max, dp[i - 1][j + k]);
    			while(l < r && dp[i - 1][q[r - 1]] + s[i][q[r - 1] - 1] <= dp[i - 1][j] + s[i][j - 1]) r --;
    			q[r ++] = j;
    			while(l < r && q[l] >= j + k) l ++;
    			dp[i][j] = max(dp[i][j], calc(i, j) + max(Max, dp[i - 1][q[l]] + s[i][q[l] - 1] - s[i][j + k - 1]));
    		}
    	}
    	int ans = 0;
    	for(int i = 1; i <= m; i ++) ans = max(ans, dp[n][i]);
    	printf("%d
    ", ans);
    	return 0;
    } 
    
  • 相关阅读:
    《构建之法》前三章读后感--软件工程
    复利计算--web版--总结--软件工程
    利率计算v2.0--web版--软件工程
    <更新日期03-31-2016> 复利计算5.0 <已改进>
    0302随笔
    有限自动机的构造与识别
    评论
    C语言文法
    词法分析 after Coding
    词法分析
  • 原文地址:https://www.cnblogs.com/hongzy/p/12316419.html
Copyright © 2011-2022 走看看