Codeforces Round #479 (Div. 3) ABCDEF

A. Wrong Subtraction

传送门:http://codeforces.com/contest/977/problem/A


题目大意:

  给一个数,末尾为0时除以10,不为0时减1,输出k次操作后的结果。


AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#define P pair<int,int>
#define ll long long
#define INF 1e10
#define M 1e9+7
#define MAX 500010
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
using namespace std;

int n, k;

int main()
{
	cin >> n >> k;
	while (k--) {
		if (n % 10 == 0)
			n /= 10;
		else
			n--;
	}
	cout << n << endl;
	return 0;
}


B. Two-gram

传送门:http://codeforces.com/contest/977/problem/B


题目大意:

  给定一个字符串,输出该字符串中出现次数最多的长度为2的子串。


思路:

  用map记录次数,遍历就好。


AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#define P pair<int,int>
#define ll long long
#define INF 1e10
#define M 1e9+7
#define MAX 500010
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
using namespace std;

int n;
string str;
map <string, int> mp;

int main()
{
	cin >> n; getchar();
	cin >> str;
	for (int i = 0; i < n - 1; i++) 
		mp[str.substr(i,2)]++;
	int maxx = -1;
	string ans = "";
	for (int i = 0; i < n - 1; i++) {
		if (maxx < mp[str.substr(i, 2)]) {
			maxx = mp[str.substr(i, 2)];
			ans = str.substr(i, 2);
		}
	}
	cout << ans << endl;
	return 0;
}

C. Less or Equal

传送门:http://codeforces.com/contest/977/problem/C


题目大意:

  给出n个数字,求x,使正好有k个数字小于等于x。


思路:

  先排序,设最小的数字为a。

  若k=0,如果a为1,则输出-1,否则输出a-1。

  若k=n,直接输出10^9。

  否则,判断第k个数和第k+1个数是否相等,相等输出-1,不相等输出第k个数。


AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#define P pair<int,int>
#define ll long long
#define INF 1e10
#define M 1e9+7
#define MAX 500010
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
using namespace std;

int a[200010];
int n, k;

int main()
{
	cin >> n >> k;
	for (int i = 0; i < n; i++)
		cin >> a[i];	

	sort(a, a + n);

	if (k == n) {
		cout << 1000000000 << endl;
		return 0;
	}
	else if (k == 0) {
		if (a[0] == 1)
			cout << -1 << endl;
		else
			cout << a[0] - 1 << endl;
		return 0;
	}

	if (a[k - 1] == a[k])
		cout << -1 << endl;
	else
		cout << a[k - 1] << endl;
	return 0;
}


D. Divide by three, multiply by two

传送门:http://codeforces.com/contest/977/problem/D


题目大意:

  给定一个序列,将这个序列排序,使得对于每个数都是前一个数的2倍或1/3倍。


思路:

  由于是*2和/3,所以所有数字都不一样,可以用map来记录每个数字对应的位置,由于最大也就100个数字,所以dfs对于每个数字都跑一遍就可以了。


AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#define P pair<int,int>
#define ll long long
#define INF 1e10
#define M 1e9+7
#define MAX 500010
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
using namespace std;

int n;
bool judge;
ll a[110];
ll ans[110];
map <ll, int> mp;

void dfs(int i,int cnt)
{
	if (judge)
		return;
	ans[cnt] = a[i];
	if (cnt == n ) {
		judge = true;
		return;
	}
	if (a[i] % 3 == 0 && mp[a[i] / 3] != 0)
		dfs(mp[a[i] / 3], cnt + 1);
	
	if (mp[a[i] * 2] != 0)
		dfs(mp[a[i] * 2], cnt + 1);
}

int main()
{
	judge = false;
	cin >> n;
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
		mp[a[i]] = i;
	}

	for (int i = 1; i <= n; i++) {
		if (judge)break;
		dfs(i, 1);
	}

	for (int i = 1; i <= n; i++)
		cout << ans[i] << ' ';
	cout << endl;
	return 0;
}


E. Cyclic Components

传送门:http://codeforces.com/contest/977/problem/E


题目大意:

  给n个点,m条边,问有多少个环,环内所涉及的点不与环外的任何点有边相连。


思路:

  利用vector来记录边。

  若一个顶点所连接的边的条数不为2,则肯定不是某个环中的点,设为访问过的点。

  遍历没访问过的点作为起始点,并且将该起始点标记为访问过的点,根据相连的边到达下一个顶点,判断该顶点是否被访问过以及条数是否为2,若有一项不满足则说明从起始点到这个顶点的所涉及的所有点都不可能是某个环中的点,若都满足则设为访问过的点并继续找下一个顶点,直到找到起始点说明找到了一个环。

  重复上面的动作直到所有点都访问过。


AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#define P pair<int,int>
#define ll long long
#define INF 1e10
#define M 1e9+7
#define MAX 500010
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
using namespace std;

int n, m, x, y;
vector<int> node[200010];
int used[200010];

int main()
{
	int ans = 0;
	cin >> n >> m;
	while (m--) {
		cin >> x >> y;
		node[x].push_back(y);
		node[y].push_back(x);
	}
	for (int i = 0; i < n; i++)
		if (node[i].size() != 2)
			used[i] = 1;

	for (int i = 0; i < n; i++) {
		if (used[i] == 0 && node[i].size() == 2) {
			used[i] = 1;
			int start = i;
			int u = i;
			int v = node[i][0];
			while (v != start) {
				if (used[v] == 1 || node[v].size() != 2) {
					used[v] = 1;
					break;
				}

				used[v] = 1;

				if (node[v][0] == u) {
					u = v;
					v = node[v][1];
				}
				else {
					u = v;
					v = node[v][0];
				}
			}

			if (v == start)
				ans++;
		}
	}
	cout << ans << endl;
	return 0;
}


F. Consecutive Subsequence

传送门:http://codeforces.com/contest/977/problem/F


题目大意:

  给一个数列,找出其中最长的公差为1的等差数列。


思路:

  用一个map来记录以n结尾的等差数列的长度,其中mp[n]=mp[n-1]+1。


AC代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<cstdlib>
#include<utility>
#include<algorithm>
#include<utility>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<cmath>
#include<map>
#define P pair<int,int>
#define ll long long
#define INF 1e10
#define M 1e9+7
#define MAX 500010
#define lson id*2,l,mid
#define rson id*2+1,mid+1,r
using namespace std;

int n;
int a[200010];
map<int, int> mp;

int main()
{
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> a[i];

	int maxx = -1;
	int number = -1;
	for (int i = 1; i <= n; i++) {
		if (mp.find(a[i] - 1) == mp.end())
			mp[a[i] - 1] = 0;
		mp[a[i]] = mp[a[i] - 1] + 1;
		if (maxx < mp[a[i]]) {
			maxx = mp[a[i]];
			number = a[i];
		}
	}

	cout << maxx << endl;
	stack <int> s;
	for (int i = n ; i >= 1; i--) {
		if (a[i] == number) {
			number--;
			s.push(i);
		}
	}

	while (!s.empty()) {
		cout << s.top() << " ";
		s.pop();
	}
	cout << endl;
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值