zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 204 A-E简要题解

    A:判断一下给出的俩是一样的还是不一样的,分成两类输出。

    B:对于每个 (A_i),答案加上 (max(A_i-10,0))

    C:对于每个点 (mathcal{O}(n)) dfs 一遍能到达的点有多少个,加起来即可。

    D:dp,设 (f_{i,j}) 为考虑前 (i) 个,是否存在“分成的两组较大的大小为 (j) ”的方案,dp复杂度 (mathcal{O}(n^2T))

    E:Dij,每次算距离的时候三分一下,三分的时候按照不下取整算实数来三分,因为如果下取整的话会出现平的一段导致不能三分。

    详细题解和代码有空补。

    A

    #include<iostream>
    #include<cstdio>
    template <typename T> T Max(T x, T y) { return x > y ? x : y; }
    template <typename T> T Min(T x, T y) { return x < y ? x : y; }
    template <typename T>
    T& read(T& r) {
    	r = 0; bool w = 0; char ch = getchar();
    	while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
    	while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
    	return r = w ? -r : r;
    }
    signed main() {
    	int a, b;
    	read(a); read(b);
    	if(a == b) printf("%d
    ", a);
    	else printf("%d
    ", 3 - a - b);
    	return 0;
    }
    

    B

    #include<iostream>
    #include<cstdio>
    template <typename T> T Max(T x, T y) { return x > y ? x : y; }
    template <typename T> T Min(T x, T y) { return x < y ? x : y; }
    template <typename T>
    T& read(T& r) {
    	r = 0; bool w = 0; char ch = getchar();
    	while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
    	while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
    	return r = w ? -r : r;
    }
    const int N = 1010;
    int n, a[N], sum;
    signed main() {
    	read(n);
    	for(int i = 1; i <= n; ++i) read(a[i]), sum += Max(0, a[i] - 10);
    	printf("%d
    ", sum); 
    	return 0;
    }
    

    C

    #include<iostream>
    #include<cstdio>
    typedef long long ll;
    template <typename T> T Max(T x, T y) { return x > y ? x : y; }
    template <typename T> T Min(T x, T y) { return x < y ? x : y; }
    template <typename T>
    T& read(T& r) {
    	r = 0; bool w = 0; char ch = getchar();
    	while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
    	while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
    	return r = w ? -r : r;
    }
    const int N = 2010;
    int n, m, ent, head[N];
    struct Edge {
    	int next, to;
    }e[N << 1];
    inline void add(int x, int y) {
    	e[++ent].to = y; e[ent].next = head[x]; head[x] = ent;
    }
    ll cnt, ans;
    bool vis[N];
    void dfs(int x) {
    	if(vis[x]) return ;
    	vis[x] = 1; ++cnt;
    	for(int i = head[x]; i; i = e[i].next) dfs(e[i].to);
    }
    signed main() {
    	read(n); read(m);
    	for(int i = 1, u, v; i <= m; ++i) {
    		read(u); read(v);
    		add(u, v); //add(v, u);
    	}
    	for(int i = 1; i <= n; ++i) {
    		for(int j = 1; j <= n; ++j) vis[j] = 0;
    		cnt = 0;
    		dfs(i);
    		ans += cnt;
    		}
    	printf("%lld
    ", ans);
    	return 0;
    }
    

    D

    #include<iostream>
    #include<cstdio>
    template <typename T> T Max(T x, T y) { return x > y ? x : y; }
    template <typename T> T Min(T x, T y) { return x < y ? x : y; }
    template <typename T>
    T& read(T& r) {
    	r = 0; bool w = 0; char ch = getchar();
    	while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
    	while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
    	return r = w ? -r : r;
    }
    const int N = 110;
    int n, a[N], s[N];
    bool f[N][N*1000];
    signed main() {
    	read(n); 
    	for(int i = 1; i <= n; ++i) read(a[i]), s[i] = s[i-1] + a[i];
    	f[1][a[1]] = 1;
    	for(int i = 1; i < n; ++i) {
    		for(int j = 0; j <= s[i]; ++j)
    			if(f[i][j])
    				f[i+1][Max(j+a[i+1], s[i]-j)] = 1,
    				f[i+1][Max(j, s[i]-j+a[i+1])] = 1;
    	} int ans = 0;
    	for(int i = 0; i <= s[n]; ++i)
    		if(f[n][i]) {
    			ans = i;
    			break;
    		}
    	printf("%d
    ", ans);
    	return 0;
    } 
    

    貌似直接取根号就是最优的,赛时看了一眼觉得像对钩函数就莽了一手三分...

    E

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #define int long long
    typedef double ld;
    typedef long long ll;
    typedef std::pair<long long, int> pli;
    #define mp std::make_pair
    #define pp push_back
    template <typename T> T Max(T x, T y) { return x > y ? x : y; }
    template <typename T> T Min(T x, T y) { return x < y ? x : y; }
    template <typename T>
    T& read(T& r) {
    	r = 0; bool w = 0; char ch = getchar();
    	while(ch < '0' || ch > '9') w = ch == '-' ? 1 : 0, ch = getchar();
    	while(ch >= '0' && ch <= '9') r = r * 10 + (ch ^ 48), ch = getchar();
    	return r = w ? -r : r;
    }
    const int N = 200010;
    const ll INF = 0x7fffffffffffffff;
    std::priority_queue<pli>q;
    int n, m, head[N], ent;
    ll dis[N];
    bool vis[N];
    struct Edge {
    	int next, to, C, D;
    }e[N << 1];
    inline void add(int x, int y, int c, int d) {
    	e[++ent].to = y;
    	e[ent].C = c; e[ent].D = d;
    	e[ent].next = head[x]; head[x] = ent;
    }
    inline ld f(int p, int x, int t) {
    	return 1ll * t + 1.0 * e[p].D / (x + t + 1);
    }
    inline ll fl(int p, int x, int t) {
    	return 1ll * t + std::floor(1.0 * e[p].D / (x + t + 1));
    }
    ll calc(int p, int x) {
    	int l = 0, r = e[p].D;
    	ll ans = INF;
    	while(l <= r) {
    		int y = (r - l) / 3, mid1 = l + y, mid2 = mid1 + y;
    		ans = Min(ans, fl(p, x, l));
    		ans = Min(ans, fl(p, x, r));
    		ans = Min(ans, fl(p, x, mid1));
    		ans = Min(ans, fl(p, x, mid2));
    		if(f(p, x, mid1) >= f(p, x, mid2)) l = mid1+1;
    		else r = mid2-1;
    	}
    	ans = Min(ans, fl(p, x, l)); ans = Min(ans, fl(p, x, r));
    	ans = Min(ans, fl(p, x, l+1)); ans = Min(ans, fl(p, x, r+1));
    	if(l) ans = Min(ans, fl(p, x, l-1));
    	if(r) ans = Min(ans, fl(p, x, r-1));
    	return ans + e[p].C;
    }
    signed main() {
    	read(n); read(m);
    	for(int i = 1, u, v, c, d; i <= m; ++i) {
    		read(u); read(v); read(c); read(d);
    		add(u, v, c, d); add(v, u, c, d);
    	}
    	for(int i = 2; i <= n; ++i) dis[i] = INF;
    	q.push(mp(0, 1));
    	while(!q.empty()) {
    		int x = q.top().second; q.pop();
    		if(vis[x]) continue;
    		vis[x] = 1;
    		for(int i = head[x]; i; i = e[i].next) {
    			int v = e[i].to;
    			ll cc = calc(i, dis[x]);
    			if(dis[v] > dis[x] + cc) {
    				dis[v] = dis[x] + cc;
    				q.push(mp(-dis[v], v));
    			}
    		}
    	}
    	printf("%lld
    ", dis[n] == INF ? -1 : dis[n]);
    	return 0;
    }
    
  • 相关阅读:
    SDL 开发实战(三):使用 SDL 绘制基本图形
    SDL 开发实战(二):SDL 2.0 核心 API 解析
    SDL 开发实战(一):SDL介绍及开发环境配置
    开源播放器 ijkplayer (六) :Android 下使用 ijkplayer 异常处理思路
    音视频编解码技术(二):AAC 音频编码技术
    FFmpeg开发实战(五):FFmpeg 抽取音视频的视频数据
    FFmpeg开发实战(四):FFmpeg 抽取音视频的音频数据
    FFmpeg开发实战(三):FFmpeg 打印音视频Meta信息
    FFmpeg开发实战(二):FFmpeg 文件操作
    FFmpeg开发实战(一):FFmpeg 打印日志
  • 原文地址:https://www.cnblogs.com/do-while-true/p/14856498.html
Copyright © 2011-2022 走看看