Codeforces Round #726 (Div.2) A-E1 题解

A. Arithmetic Array

题目大意:一串数,求添加多少个非负整数后平均值为1

代码:

//CF726A
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)

typedef long long ll;

#define INF 0x3f3f3f3f
const double EPS = 1e-18;
const int MOD = 1e9 + 7;
const int maxn = 1e5 + 1;

int T, N;

void solve()
{
	int num;
	int sum = 0;
	for (int i = 0; i < N; i++)
	{
		cin >> num;
		sum += num;
	}
	if (sum == N)
		cout << 0 << endl;
	else if (sum < N)
		cout << 1 << endl;
	else
		cout << sum - N << endl;
}

int main()
{
	IOS;
	cin >> T;
	while (T--)
	{
		cin >> N;
		solve();
	}
	return 0;
}

B. Bad Boy

题目大意:一个NxM的区域,一个人在(i,j),只能向上下左右移动,区域内有两个球,求球的位置使得这个人拿回两个球后回到起始位置的路程最长。

思路:放在区域的对角就一定最远。

代码:

//CF726B
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)

typedef long long ll;

#define INF 0x3f3f3f3f
const double EPS = 1e-18;
const int MOD = 1e9 + 7;
const int maxn = 1e5 + 1;

int T, N, M, i, j;

void solve()
{
	cout << 1 << ' ' << 1 << ' ' << N << ' ' << M << ' ' << endl;
}

int main()
{
	IOS;
	cin >> T;
	while (T--)
	{
		cin >> N >> M >> i >> j;
		solve();
	}

	return 0;
}

C. Challenging Cliffs

题目大意:一个n个数的序列h,相差最小的两个数必须放在一头一尾,给出一个序列,使得满足h[i]<=h[i+1]的i最多。

思路:排序,然后找出相差最小的两个数h[i],h[j](j=i+1)放在一头一尾,之后在二者之间先输出大于h[j]的数,再输出小于h[i]的数即可,这样只有1处会不满足,所以满足条件的i的个数为n-2。

代码: 

//CF726C
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)

typedef long long ll;

#define INF 0x3f3f3f3f
const double EPS = 1e-18;
const int MOD = 1e9 + 7;
const int maxn = 2e5 + 10;

int T, N, h[maxn];

void solve()
{
	sort(h, h + N);
	int si = -1, ti = -1;
	int s, t, dmin = INF;
	for (int i = 1; i < N; i++)
	{
		if (h[i] - h[i - 1] < dmin)
		{
			dmin = h[i] - h[i - 1];
			s = h[i - 1];
			t = h[i];
			si = i - 1;
			ti = i;
		}
	}

		cout << s << ' ';
		for (int i = ti + 1; i < N; i++)
			cout << h[i] << ' ';
		for (int i = 0; i < si; i++)
			cout << h[i] << ' ';
		cout << t << endl;
}

int main()
{
	IOS;
	cin >> T;
	while (T--)
	{
		cin >> N;
		for (int i = 0; i < N; i++)
			cin >> h[i];
		solve();
	}

	return 0;
}

D. Deleting Divisors

题目大意:Alice和Bob玩游戏。Alice先手,一开始有一个数字N,每次可以让N减去除N与1以外的约数,如果无法操作则判负。

思路:显然当N转化为质数的时候就会输,过程中N总共会有3种情况:

1) 奇数

2)偶数但不是2的幂

3) 2的幂

先考虑N为奇数的情况,此时N的所有约数也都为奇数,所以在减去一个约数之后N就变为了偶数,而且设N=a*b,减去a之后为a(b-1),a仍是奇数,所以此时的N是虽然是偶数但不是2的幂,所以N有奇约数,即第一种情况只能转化为第二种情况。而第二种情况只要拿掉一个约数就可以回到情况1。又因为除了2之外的质数全部都是奇数,所以当N为奇数时,先手必败,而对称地,当N为偶数但不是2的幂时,后手必败。

而对于第三种情况,设N=2^k,能够减去的约数只能是2^m(m<k),移去后N变为2^m(2^(k-m)-1)

因为如果操作后转化为情况二就自己就必败了,所以只能让N继续转化为情况三,也就是只能移去约数2^(k-1),让N=N/2。因为2^1为质数,所以当N为2的奇数次幂时,先手必败,为2的偶数次幂时,后手必败。

代码:

//CF726D
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)

typedef long long ll;

#define A "Alice"
#define B "Bob"
#define INF 0x3f3f3f3f
const double EPS = 1e-18;
const int MOD = 1e9 + 7;
const int maxn = 1e9 + 10;

int T, N;

void solve()
{
	if (N % 2)
		cout << B << endl;
	else
	{
		int x = 0;
		while (!(N % 2) && N >= 2)
		{
			N /= 2;
			x++;
		}
		if (N != 1)
			cout << A << endl;
		else
		{
			if (x % 2)
				cout << B << endl;
			else
				cout << A << endl;
		}
	}
}

int main()
{
	IOS;
	cin >> T;
	while (T--)
	{
		cin >> N;
		solve();
	}

	return 0;
}

E1. Erase and Extend (Easy Version)

题目大意:有一个长为N的字符串,有两种操作:1)将字符串复制一份接在后面成为一个新的字符串,2)删去字符串末尾的字符,以上操作不限次数,求若干次操作后生成的字典序最小的长度为K的字符串。

思路:因为N,K比较小,所以可以遍历初始字符串的所有前缀。不断执行操作1,直到长度>=K,之后再进行若干次操作2,将每个前缀如此操作后所得的字符串作比较,字典序最小的就是答案了。

因为对于每个前缀,如果说在若干次操作1)之间差入几次操作2)所得的字符串的字典序会更小,那么就说明该前缀的某一前缀字典序小于其某一等长后缀。那么就显然对于初始串的一个更短的前缀值行之前的操作要比这种情况还要更优,所以尽管对于每个前缀所得字符串不是最优的,但是遍历所有前缀之后不会错过最优解。

代码:

//CF-726.E1
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)

typedef long long ll;

#define INF 0x3f3f3f3f
const double EPS = 1e-18;
const int MOD = 1e9 + 7;
const int maxn = 1e5 + 1;

int N, K;
string s;
string ans;

void dfs(int k, string str)
{
	if (str.size() > k)
	{
		if (ans.empty())
			ans = str.substr(0, k);
		else
			ans = min(ans, str.substr(0, k));
		return;
	}
	dfs(k, str + str);
}

void solve()
{
	for (int i = N; i > 0; i--)//for each prefix
		dfs(K, s.substr(0, i));
	cout << ans << endl;
}
int main()
{
	IOS;
	cin >> N >> K >> s;
	solve();

	return 0;
}
posted @ 2022-03-02 20:08  Prgl  阅读(38)  评论(0)    收藏  举报