zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 155 简要题解

    AtCoder Beginner Contest 155

    A:签到失败,WA一次。

    int main() {
    	int a, b, c;
    	cin >> a >> b >> c;
    	if(a == b && b == c) cout << "No";
    	else if(a == b || a == c || b == c) cout << "Yes";
    	else cout << "No";
    	return 0;
    } 
    

    B:签到失败乘2,这题又WA一次。

    int main() {
    	int n; scanf("%d", &n); bool ok = 1;
    	while(n --) {
    		int x; scanf("%d", &x);
    		if(x % 2 == 0 && (x % 3 != 0 && x % 5 != 0)) {
    			ok = 0;
    		}
    	}
    	puts(ok ? "APPROVED" : "DENIED");
    	return 0;
    } 
    

    C:直接开map。

    string s[200010];
    vector<string> vec;
    map<string, int> Map;
    int main() {
    	int n; scanf("%d", &n); int ans = 0;
    	for(int i = 1; i <= n; i ++) {
    		cin >> s[i];
    		ans = max(ans, ++ Map[s[i]]);
    	}
    	for(int i = 1; i <= n; i ++) {
    		if(Map[s[i]] == ans) {
    			Map[s[i]] = 0;
    			vec.pb(s[i]);
    		}
    	}
    	sort(vec.begin(), vec.end());
    	for(auto s : vec) printf("%s
    ", s.c_str());
    	return 0;
    } 
    

    D:二分 + two-pointer,正负要讨论,注意不要使用实数运算求floor和ceil。代码非常丑。

    
    const int N = 2e5 + 10;
    int n, rpos, a[N]; ll k;
    ll C(ll n) { return n * (n - 1) / 2; }
    ll fl(ll a, ll b) {
    	bool f = (a < 0) ^ (b < 0);
    	if(a < 0) a = -a;
    	if(b < 0) b = -b;
    	return f ? - ( a / b + 1 ) : a / b;
    }
    ll cl(ll a, ll b) {
    	bool f = (a < 0) ^ (b < 0);
    	if(a < 0) a = -a;
    	if(b < 0) b = -b;
    	return f ? - ( a / b ) : (a + b - 1) / b;
    }
    int main() {
    	scanf("%d%lld", &n, &k);
    	for(int i = 1; i <= n; i ++) scanf("%d", a + i);
    	sort(a + 1, a + n + 1);
    	ll l = 0, r = 0, z = 0, L = 0, R = 0, Z = 0;
    	for(int i = 1; i <= n; i ++) z += a[i] == 0;
    	for(int i = 1; i <= n; i ++) l += a[i] < 0;
    	for(int i = 1; i <= n; i ++) r += a[i] > 0;
    	L = l * r; R = C(l) + C(r); Z = C(n) - L - R;
    	rpos = n + 1;
    	for(int i = 1; i <= n; i ++) if(a[i] > 0) {
    		rpos = i; break ;
    	}
    	if(k <= L) {
    		ll ql = -1e18, qr = -1, mid, ans = -233;
    		while(ql <= qr) {
    			mid = (ql + qr) >> 1;
    			ll sum = 0, now = r, cur = rpos;
    			for(int i = 1; i <= n && a[i] < 0; i ++) {
    				ll up = mid % a[i] == 0 ? mid / a[i] + 1 : cl(mid, a[i]);
    				while(now && a[cur] < up) cur ++, now --;
    				sum += now;
    			}
    			if(sum < k) ql = (ans = mid) + 1;
    			else qr = mid - 1;
    		}
    		printf("%lld
    ", ans);
    	} else if(k <= L + Z) {
    		puts("0");
    	} else {
    		k -= L + Z;
    		ll ql = 1, qr = 1e18, mid, ans = -233;
    		while(ql <= qr) {
    			mid = (ql + qr) >> 1;
    			ll sum = 0, now = r, cur = n;
    			for(int i = rpos; i <= n; i ++) {
    				ll up = mid % a[i] == 0 ? mid / a[i] - 1 : fl(mid, a[i]);
    				while(now && a[cur] > up) cur --, now --;
    				sum += cur >= i ? now - 1 : now;
    			}
    			now = l; cur = 1;
    			for(int i = n; i >= 1; i --) if(a[i] < 0) {
    				ll up = mid % a[i] == 0 ? mid / a[i] + 1 : cl(mid, a[i]);
    				while(now && a[cur] < up) cur ++, now --;
    				sum += cur <= i ? now - 1 : now;
    			}
    			sum >>= 1;
    			if(sum < k) ql = (ans = mid) + 1;
    			else qr = mid - 1;
    		}
    		printf("%lld
    ", ans);
    	}
    	return 0;
    } 
    

    E:dp[i][0/1]表示前i位,第i位要不要借给下一位,最小代价。

    char s[N];
    int dp[N][2];
    bool ok(int x) { return x >= 0 && x < 10; }
    int main() {
    	scanf("%s", s + 1);
    	int n = strlen(s + 1);
    	dp[0][1] = 1; dp[0][0] = 0;
    	for(int i = 1; i <= n; i ++) {
    		dp[i][0] = dp[i][1] = 1e9;
    		int x = s[i] - '0';
    		for(int j = 0; j < 10; j ++) {
    			if(ok(10 + j - x)) dp[i][0] = min(dp[i][0], dp[i - 1][1] + j + (10 + j - x));
    			if(ok(j - x)) dp[i][0] = min(dp[i][0], dp[i - 1][0] + j + (j - x));
    			if(ok(10 + (j - 1) - x)) dp[i][1] = min(dp[i][1], dp[i - 1][1] + j + (10 + j - 1 - x));
    			if(ok(j - 1 - x)) dp[i][1] = min(dp[i][1], dp[i - 1][0] + j + (j - 1 - x));
    		}
    	}
    	printf("%d
    ", dp[n][0]);
    	return 0;
    } 
    

    F:差分,然后区间xor变成两点同时xor。所有l和r+1连边建图,问题转换为选若干条边,一条边被选两个端点就xor上1。

    对于每个连通块dfs,如果当前子树的根状态为1就选这条边,否则不选,这样若不合法只可能根不合法。若根不合法,显然无解,因为若要选非dfs树边,一定会出现其他不合法点。

    const int N = 2e5 + 10;
    
    struct node {
    	int a, b;
    } x[N], t[N];
    int n, q, b[N];
    bool ans[N], st[N], vis[N];
    vector<pii> G[N];
    int get(int u) { return lower_bound(b + 1, b + n + 1, u) - b; }
    int getl(int u) { return upper_bound(b + 1, b + n + 1, u) - b - 1; }
    void link(int u, int v, int w) { G[u].pb(pii(v, w)); G[v].pb(pii(u, w)); }
    int dfs(int u) {
    	vis[u] = 1; int x = st[u];
    	for(auto v : G[u]) if(!vis[v.fs]) {
    		if(dfs(v.fs)) { ans[v.sc] = 1; x ^= 1; }
    	}
    	return x;
    }
    int main() {
    	scanf("%d%d", &n, &q);
    	for(int i = 1; i <= n; i ++) { scanf("%d%d", &x[i].a, &x[i].b); b[i] = x[i].a; }
    	for(int i = 1; i <= q; i ++) scanf("%d%d", &t[i].a, &t[i].b);
    	sort(b + 1, b + n + 1);
    	for(int i = 1; i <= n; i ++) { x[i].a = get(x[i].a); st[x[i].a] = x[i].b; }
    	for(int i = n + 1; i >= 1; i --) st[i] ^= st[i - 1];
    	for(int i = 1; i <= q; i ++) link(get(t[i].a), 1 + getl(t[i].b), i);
    	for(int i = 1; i <= n + 1; i ++) if(!vis[i]) {
    		if(dfs(i)) { puts("-1"); return 0; }
    	}
    	int r = 0;
    	for(int i = 1; i <= q; i ++) r += ans[i];
    	printf("%d
    ", r);
    	for(int i = 1; i <= q; i ++) if(ans[i]) printf("%d ", i);
    	return 0;
    } 
    
  • 相关阅读:
    vps云服务器建站后绑定域名的方法?
    怎么做局域网远程联机?
    解决服务器Active&nbsp;Directory环境里Windows登录性能问题办法
    搭建dns域名服务器过程
    服务器电源常见故障判断及处理方法
    有些网站为什么要使用CDN,CDN又是什么呢
    独立服务器使用技巧介绍
    云服务器和虚拟主机的区别
    CDN在中国的发展的九个年头的点点滴滴
    网络安全的攻防战争
  • 原文地址:https://www.cnblogs.com/hongzy/p/12319488.html
Copyright © 2011-2022 走看看