zoukankan      html  css  js  c++  java
  • CSP-J/S2019 做题练习(day1)

    A - Xenny and Alternating Tasks

    题面

    题解

    枚举第一天是谁做,将两个答案取(min)即可。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #define gI gi
    #define itn int
    #define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
    
    using namespace std;
    
    inline int gi()
    {
        int f = 1, x = 0; char c = getchar();
        while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
        while (c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
        return f * x;
    }
    
    int t, n, a[20003], b[20003];
    
    int main()
    {
    	//File("XENTASK");
    	t = gi();
    	while (t--)
    	{
    		n = gi();
    		for (int i = 1; i <= n; i+=1) a[i] = gi();
    		for (itn i = 1; i <= n; i+=1) b[i] = gi();
    		itn ans = 0, sum = 0;
    		for (itn j = 1; j <= n; j+=1)
    		{
    			if (j & 1) sum = sum + a[j];
    			else sum = sum + b[j];
    		}
    		for (int j = 1; j <= n; j+=1)
    		{
    			if (j & 1) ans = ans + b[j];
    			else ans = ans + a[j];
    		}
    		printf("%d
    ", min(ans, sum));
    	}
    	return 0;
    }
    

    B - Bear and Extra Number

    题面

    题解

    将数列排序,遍历数组元素,然后分类讨论:

    1. 如果是(a_i = a_{i+1}) ,那么输出(a_i)
    2. 如果(a_{i+1}-a_i>1)
      • 因为题目说有唯一解,因此(i)只能为(n-1)(1)
        • (i)(n-1),则输出(a_n)
        • (i)(1),则输出(a_1)

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #define gI gi
    #define itn int
    #define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
    
    using namespace std;
    
    inline int gi()
    {
        int f = 1, x = 0; char c = getchar();
        while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
        while (c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
        return f * x;
    }
    
    int t, n, a[100003], ans, sum;
    
    int main()
    {
    	//File("EXTRAN");
    	t = gi();
    	while (t--)
    	{
    		n = gi();
    		for (itn i = 1; i <= n; i+=1) a[i] = gi();
    		sort(a + 1, a + 1 + n);
    		for (int i = 1; i < n; i+=1)
    		{
    			if (a[i + 1] == a[i]) {printf("%d
    ", a[i]); break;}
    			if (a[i + 1] - a[i] > 1)
    			{
    				if (i == n - 1) {printf("%d
    ", a[n]); break;}
    				else if (i == 1) {printf("%d
    ", a[1]); break;}
    			}
    		}
    	}
    	return 0;
    }
    

    C - Cooking Schedule

    题面

    题解

    二分。

    注意(check)怎么写。

    第一次做时没想到二分,很遗憾。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #define int long long
    #define gI gi
    #define itn int
    #define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
    
    using namespace std;
    
    inline int gi()
    {
        int f = 1, x = 0; char c = getchar();
        while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
        while (c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
        return f * x;
    }
    
    int n, m, t, k, ans, kkk, c[1000003];
    char s[1000003];
    
    int CCC(itn x)
    {
    	int u = 0;
    	for (int i = 1; i <= n; i+=1)
    	{
    		if (i % 2 == x)
    		{
    			if (s[i] == '0') ++u;
    		}
    		else {if (s[i] == '1') ++u;}
    	}
    	return u;
    }
    
    bool check(int x)
    {
    	if (x != 1)
    	{
    		int u = 0;
    		for (itn i = 1; i <= kkk; i+=1) if (c[i] > x) u = u + c[i] / (x + 1);
    		return u <= k;
    	}
    	else {int u = min(CCC(1), CCC(0)); return u <= k;}
    }
    
    signed main()
    {
    	//File("SCHEDULE");
    	t = gi();
    	while (t--)
    	{
    		int l = 1, r = 0, uuu = 0; kkk = 0;
    		n = gi(), k = gi();
    		scanf("%s", s + 1);
    		for (int i = 1; i <= n; i+=1)
    		{
    			if (s[i] != s[i + 1])
    			{
    				c[++kkk] = i - uuu; uuu = i; r = max(r, c[kkk]);
    			}
    		}
    		while (l < r)
    		{
    			int mid = (l + r) >> 1;
    			if (check(mid)) r = mid;
    			else l = mid + 1;
    		}
    		printf("%lld
    ", r);
    	}
    	return 0;
    }
    
    

    D - Subtree Removal

    题面

    题解

    简单树形(DP)

    看似很难,实际代码很短。

    计算出每棵子树的大小,与(-X)(max)即可。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #include <vector>
    #define int long long
    #define gI gi
    #define itn int
    #define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
    
    using namespace std;
    
    inline int gi()
    {
        int f = 1, x = 0; char c = getchar();
        while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
        while (c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
        return f * x;
    }
    
    int t, n, x, fa[100003], ans, sum, k, b[100003], sz[100003];
    vector <int> e[100003];
    
    int dfs(int u, int fa)
    {
    	int o = b[u];
    	for (int i = e[u].size() - 1; ~i; i-=1)
    	{
    		int v = e[u][i];
    		if (v == fa) continue;
    		o = o + dfs(v, u);
    	}
    	return max(o, -x);
    }	   
    
    signed main()
    {
    	//File("SUBREM");
    	t = gi();
    	while (t--)
    	{
    		n = gi(), x = gi();
    		int sum = 0;
    		for (itn i = 1; i <= n; i+=1) b[i] = gi(), sz[i] = b[i], sum = sum + b[i], e[i].clear();
    		for (itn i = 1; i < n; i+=1) {int u = gi(), v = gi(); e[u].push_back(v), e[v].push_back(u);}
    		printf("%lld
    ", dfs(1, -1));
    	}
    	return 0;
    }
    
    

    E - Dish Owner

    题面

    题解

    并查集简单题。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #include <vector>
    #include <queue>
    #define gI gi
    #define itn int
    #define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
    
    using namespace std;
    
    inline int gi()
    {
        int f = 1, x = 0; char c = getchar();
        while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
        while (c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
        return f * x;
    }
    
    itn t, n, s[10003], fl, x, y, Q;
    itn a[10003], fa[10003];
    
    int getf(itn u) {if (u == fa[u]) return u; return fa[u] = getf(fa[u]);}
    
    inline void unionn(int u, int v) {
    	if (a[u] > a[v])
    	{
    		fa[v] = u;
    	}
    	else if (a[v] > a[u])
    	{
    		fa[u] = v;
    	}
    }
    
    int main()
    {
    	//File("DISHOWN");
    	t = gi();
    	while (t--)
    	{
    		n = gi();
    		for (itn i = 1; i <= n; i+=1) s[i] = gi(), a[i] = s[i], fa[i] = i;
    		Q = gi();
    		for (itn i = 1; i <= Q; i+=1)
    		{
    			fl = gi();
    			if (fl)
    			{
    				x = gi();
    				printf("%d
    ", getf(x));
    			}
    			else
    			{
    				x = gi(), y = gi();
    				int X = getf(x), Y = getf(y);
    				if (X == Y) puts("Invalid query!");
    				else unionn(X, Y);
    			}
    		}
    	}
    	return 0;
    }
    

    F - Triplets

    题面

    题解

    数学题。

    大暴力很好写,考虑如何优化。

    预处理出(a)(c)序列的前缀和。

    逐一枚举(b)序列上的数,找出(a)(c)序列中比当前枚举到的数小的数。

    计算出其对答案的贡献即可。

    代码

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <cctype>
    #define int long long
    #define gI gi
    #define itn int
    #define File(x) freopen(x".in","r",stdin);freopen(x".out","w",stdout)
    
    using namespace std;
    
    inline int gi()
    {
        int f = 1, x = 0; char c = getchar();
        while (c < '0' || c > '9') {if (c == '-') f = -1; c = getchar();}
        while (c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
        return f * x;
    }
    
    const int mod = 1000000007;
    itn t, n, p, q, r, a[100003], b[100003], c[100003], x, y, z;
    itn s1 = 1, s2 = 1, s3 = 1;
    
    signed main()
    {
    	//File("SUMQ");
    	t = gi();
    	while (t--)
    	{
    		p = gi(), q = gi(), r = gi();
    		for (int i = 1; i <= p; i+=1) a[i] = gi();
    		for (int i = 1; i <= q; i+=1) b[i] = gi();
    		for (itn i = 1; i <= r; i+=1) c[i] = gi();
    		sort(a + 1, a + 1 + p); sort(b + 1, b + 1 + q); sort(c + 1, c + 1 + r);
    		int p1 = 1, p2 = 1, c1 = 0, c2 = 0, s1 = 0, s2 = 0, ans = 0;
    	   	for (int i = 1; i <= q; i+=1)
    	   	{
    		   	while (p1 <= p && a[p1] <= b[i])
    		   	{
    		   		s1 = (s1 + a[p1]) % mod;
    		   		++c1, ++p1;
    		   	}
    			while (p2 <= r && c[p2] <= b[i])
    		   	{
    				s2 = (s2 + c[p2]) % mod;
    			   	++c2, ++p2;
    	   		}
    	   		ans = (ans % mod + c1 * c2 % mod * b[i] % mod * b[i] % mod) % mod;
    	   		ans = (ans % mod + b[i] * (s1 * c2 % mod + s2 * c1 % mod) % mod) % mod;
    	   		ans = (ans % mod + s1 * s2 % mod) % mod; 
    	   	}
    	   	printf("%lld
    ", ans % mod);
    	}
    	return 0;
    }
    

    总结

    这次练习第一次做的时候做得一般般。

    做题的策略要更好一点。

    细节地方要注意。

  • 相关阅读:
    单例模式
    Curator Zookeeper分布式锁
    LruCache算法原理及实现
    lombok 简化java代码注解
    Oracle客户端工具出现“Cannot access NLS data files or invalid environment specified”错误的解决办法
    解决mysql Table ‘xxx’ is marked as crashed and should be repaired的问题。
    Redis 3.0 Cluster集群配置
    分布式锁的三种实现方式
    maven发布项目到私服-snapshot快照库和release发布库的区别和作用及maven常用命令
    How to Use Convolutional Neural Networks for Time Series Classification
  • 原文地址:https://www.cnblogs.com/xsl19/p/11277879.html
Copyright © 2011-2022 走看看