zoukankan      html  css  js  c++  java
  • Codeforces Round #479 (Div. 3) 题解 977A 977B 977C 977D 977E 977F

    A. Wrong Subtraction

    题目大意:

    定义一种运算,让你去模拟

    题解:

    模拟

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <cmath>
    inline int max(int a, int b){return a > b ? a : b;}
    inline int min(int a, int b){return a < b ? a : b;}
    inline int abs(int x){return x < 0 ? -x : x;}
    inline void swap(int &x, int &y){int tmp = x;x = y;y = tmp;}
    inline void read(int &x)
    {
    	x = 0;char ch = getchar(), c = ch;
    	while(ch < '0' || ch > '9') c = ch, ch = getchar();
    	while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    	if(c == '-') x = -x;
    }
    const int INF = 0x3f3f3f3f;
    
    int n, k; 
    int num[20], len;
    
    int main()
    {
    	read(n), read(k);
    	while(n) num[++ len] = n % 10, n /= 10;
    	int i = 1;
    	for(;k;-- k)
    	{
    		if(num[i]) -- num[i];
    		else ++ i;
    	}
    	for(int j = len;j >= i;-- j) printf("%d", num[j]);
    	return 0;
    }
    

    B. Two-gram

    题目大意

    找在串S出现次数最多的串S的子串

    题解

    暴力枚举,比较

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <cmath>
    inline int max(int a, int b){return a > b ? a : b;}
    inline int min(int a, int b){return a < b ? a : b;}
    inline int abs(int x){return x < 0 ? -x : x;}
    inline void swap(int &x, int &y){int tmp = x;x = y;y = tmp;}
    inline void read(int &x)
    {
    	x = 0;char ch = getchar(), c = ch;
    	while(ch < '0' || ch > '9') c = ch, ch = getchar();
    	while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    	if(c == '-') x = -x;
    }
    const int INF = 0x3f3f3f3f;
    
    char s[1000], now;
    int n, ans, cnt, p;
    
    int main()
    {
    	read(n);
    	scanf("%s", s + 1);
    	for(now = 1;now < n;++ now)
    	{
    		cnt = 0;
    		for(int j = 1;j < n;++ j)
    			if(s[now] == s[j] && s[now + 1] == s[j + 1]) ++ cnt;
    		if(cnt > ans) ans = cnt, p = now;
    	}
    	printf("%c%c", s[p], s[p + 1]);
    	return 0;
    }
    

    C. Less or Equal

    题目大意:

    给你一个数字序列和序列长度n,给你一个非负整数k,问是否存在一个数x,使得序列中小于等于x的元素的个数恰好为k。

    题解:

    排序后看第k个和第k+1个是否相等。
    注意k=0的情况,需要特判。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <cmath>
    inline int max(int a, int b){return a > b ? a : b;}
    inline int min(int a, int b){return a < b ? a : b;}
    inline int abs(int x){return x < 0 ? -x : x;}
    inline void swap(int &x, int &y){int tmp = x;x = y;y = tmp;}
    inline void read(int &x)
    {
    	x = 0;char ch = getchar(), c = ch;
    	while(ch < '0' || ch > '9') c = ch, ch = getchar();
    	while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    	if(c == '-') x = -x;
    }
    const int INF = 0x3f3f3f3f;
    
    int n, k, num[1000000];
    
    int main()
    {
    	read(n), read(k);
    	for(int i = 1;i <= n;++ i) read(num[i]);
    	std::sort(num + 1, num + 1 + n);
    	if(!k)
    	{
    		if(num[1] <= 1) printf("-1");
    		else printf("1");
    		return 0;
    	}
    	if(num[k] == num[k + 1]) printf("-1");
    	else printf("%d", num[k]);
    	return 0;
    }
    

    D. Divide by three, multiply by two

    题目大意:

    给你一一堆数,让你把他们排序,要求对于相邻两个元素(a_i,a_{i+1}),满足(a_I imes 2 = a_{i+1})(a_i div 3 = a_{i+1})保证答案存在

    题解:

    由于2和3互质,所以对于任意一个数(a)(a div 3)不可能通过( imes 2)(div 3)操作变成(a imes 2)。这也就意味着如果把序列里每个数看做点,每个数向它能变成的序列里的数连一条边,一定是一条链。
    暴力建链,找头就行了。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <cmath>
    inline long long max(long long a, long long b){return a > b ? a : b;}
    inline long long min(long long a, long long b){return a < b ? a : b;}
    inline long long abs(long long x){return x < 0 ? -x : x;}
    inline void swap(long long &x, long long &y){long long tmp = x;x = y;y = tmp;}
    inline void read(long long &x)
    {
    	x = 0;char ch = getchar(), c = ch;
    	while(ch < '0' || ch > '9') c = ch, ch = getchar();
    	while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    	if(c == '-') x = -x;
    }
    const long long INF = 0x3f3f3f3f;
    
    long long num[1000], nxt[1000], tag[1000], n;
    
    int main()
    {
    	read(n);
    	for(long long i = 1;i <= n;++ i) read(num[i]);
    	for(long long i = 1;i <= n;++ i)
    		for(long long j = 1;j <= n;++ j)
    			if(i == j) continue;
    			else if(num[i] * 2 == num[j] || num[i] == 3 * num[j]) nxt[i] = j, tag[j] = 1;
    	for(long long i = 1;i <= n;++ i)
    		if(!tag[i])
    		{
    			while(i) printf("%I64d ", num[i]), i = nxt[i];
    			return 0;
    		}
    	return 0;
    }
    

    E. Cyclic Components

    题目大意:

    给你一张图,问你里面有多个连通分量是一个简单环。

    题解:

    按照找连通分量的过程dfs,如果一个点度数大于2,那么不可能形成简单环;如果每个点度数都小于2,且dfs过程中走回到某个已经走过的点了,就是简单环。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <cmath>
    inline int max(int a, int b){return a > b ? a : b;}
    inline int min(int a, int b){return a < b ? a : b;}
    inline int abs(int x){return x < 0 ? -x : x;}
    inline void swap(int &x, int &y){int tmp = x;x = y;y = tmp;}
    inline void read(int &x)
    {
    	x = 0;char ch = getchar(), c = ch;
    	while(ch < '0' || ch > '9') c = ch, ch = getchar();
    	while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    	if(c == '-') x = -x;
    }
    const int INF = 0x3f3f3f3f;
    
    struct Edge
    {
    	int u, v, nxt;
    	Edge(int _u, int _v, int _nxt){u = _u, v = _v, nxt = _nxt;}
    	Edge(){}
    }edge[2000010];
    int head[2000010], cnt, vis[2000010], n, m, tmp1, tmp2, flag1, flag2, ans, fa[2000010];
    inline void insert(int a, int b)
    {
    	edge[++ cnt] = Edge(a, b, head[a]), head[a] = cnt;
    }
    int find(int x)
    {
    	return x == fa[x] ? x : fa[x] = find(fa[x]);
    }
    
    void dfs(int x, int pre)
    {
    	vis[x] = 1;
    	int tot = 0;
    	for(int pos = head[x];pos;pos = edge[pos].nxt)
    	{
    		++ tot;
    		int v = edge[pos].v;
    		if(v == pre) continue;
    		int f1 = find(x), f2 = find(v);
    		if(fa[f1] == fa[f2]) flag2 = 1;
    		if(vis[v]) continue;
    		else fa[f1] = f2;
    		dfs(v, x);
    	}
    	if(tot > 2) flag1 = 0;
    }
    
    int main()
    {
    	read(n), read(m);
    	for(int i = 1;i <= n;++ i) fa[i] = i;
    	for(int i = 1;i <= m;++ i)
    		read(tmp1), read(tmp2), insert(tmp1, tmp2), insert(tmp2, tmp1);
    	for(int i = 1;i <= n;++ i)
    		if(!vis[i])
    		{
    			flag1 = 1, flag2 = 0, dfs(i, -1);
    			ans += flag1 & flag2;
    		}
    	printf("%d", ans);
    	return 0;
    }
    

    F. Consecutive Subsequence

    题目大意:

    给你一个序列,让你找一个单调递增的公差为1的最长子序列。

    题解:

    先离散化,(dp[i])表示以(i)为结尾的最长子序列长度,(tong[i])表示数(i)在前面已经确定的(dp)状态中,数字为(ti)的位置上的最大的(dp)值。
    转移即可,用链表记录一下方案。

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    #include <vector>
    #include <stack>
    #include <cmath>
    inline int max(int a, int b){return a > b ? a : b;}
    inline int min(int a, int b){return a < b ? a : b;}
    inline int abs(int x){return x < 0 ? -x : x;}
    inline void swap(int &x, int &y){int tmp = x;x = y;y = tmp;}
    inline void read(int &x)
    {
    	x = 0;char ch = getchar(), c = ch;
    	while(ch < '0' || ch > '9') c = ch, ch = getchar();
    	while(ch <= '9' && ch >= '0') x = x * 10 + ch - '0', ch = getchar();
    	if(c == '-') x = -x;
    }
    const int INF = 0x3f3f3f3f;
    
    int dp[1000010], num[1000010], pos[1000010], pre[1000010], tong[1000010], n, tot, ans, p;
    struct Node
    {
    	int rank, num;
    }node[1000010];
    bool cmp(Node a, Node b)
    {
    	return a.num < b.num;
    }
    void dfs(int x)
    {
    	if(!x) return;
    	dfs(pre[x]);
    	printf("%d ", x);
    }
    int main()
    {
    	read(n);
    	for(int i = 1;i <= n;++ i) read(node[i].num), node[i].rank = i, dp[i] = 1;
    	std::sort(node + 1, node + 1 + n, cmp);
    	for(int i = 1;i <= n;++ i)
    	{
    		if(node[i].num != node[i - 1].num) ++ tot;
    		if(node[i].num - node[i - 1].num > 1) ++ tot;
    		pos[tot] = node[i].num, num[node[i].rank] = tot;
    	}
    	for(int i = 1;i <= n;++ i)
    	{
    		dp[i] += dp[tong[num[i] - 1]], pre[i] = tong[num[i] - 1];
    		if(dp[tong[num[i]]] < dp[i])
    			tong[num[i]] = i; 
    	}
    	for(int i = 1;i <= n;++ i)
    		if(dp[i] > ans) ans = dp[i], p = i;
    	printf("%d
    ", ans);
    	dfs(p);
    	return 0;
    }
    

    针水。

  • 相关阅读:
    封装小程序http请求
    ES6为数组做的扩展
    练习题
    二叉树的遍历
    快速搭建vue项目
    收集的前端面试大全
    ios兼容webp格式的图片
    小程序开发API之获取启动参数
    使用HTML编写邮件
    深入理解javascript原型和闭包(9)——this
  • 原文地址:https://www.cnblogs.com/huibixiaoxing/p/9006246.html
Copyright © 2011-2022 走看看