Codeforces Round #739 (Div. 3)

链接:https://codeforces.com/contest/1560

总体评价:区分度不错,比之前的div3要难一些。

A

预处理出前\(1000\)个,直接输出即可。

#include <bits/stdc++.h>
const int N = 100050;
const int INF = 1 << 30;
typedef long long ll;
using namespace std;
int n, x, num, ans[N];
int main() {
	cin >> n;
	for(int i = 1; num <= 1000; i++) {
		if(i % 10 == 3 || i % 3 == 0)
			continue;
		ans[++num] = i;
	}
	for(int i = 1; i <= n; i++) {
		cin >> x;
		cout << ans[x] << endl;
	}
	return 0;
}

B

简简单单画出前几个的情况可以找到规律,加入一些特判的点即可。

#include <bits/stdc++.h>
const int N = 100050;
const int INF = 1 << 30;
typedef long long ll;
using namespace std;
int t, a, b, c, d;
int main() {
	cin >> t;
	while(t--) {
		cin >> a >> b >> c;
		d = abs(a - b);
		if(abs(a - b) == 1 || min(a, b) > abs(a - b) || c > 2 * d) {
			cout << "-1" << endl;
			continue;
		}
		c <= d ? cout << c + d << endl : cout << c - d << endl;
	}
	return 0;
}

C

也是找规律题。以左上角的\(1\)为中心,向外画圈,看成{1},{2,3,4},{5,6,7,8,9}......这样分组。

看第\(1\)列,\(1,4,9,....n^2\)。看第一行,\(1,2,5,...,(n-1)^2+1\)。看左上到右下的那条对角线,\(1,3,7,...,n^2-n+1\)。

首先初步判定\(k\)是在第几组(环),\(\sqrt{10^9} < 32000\),时间复杂度是可以接受的。

然后再判断得到\(k\)时是行不变还是列不变,输出即可。

#include <bits/stdc++.h>
const int N = 100050;
const int INF = 1 << 30;
typedef long long ll;
using namespace std;
int t, x, n;
int main() {
	cin >> t;
	while(t--) {
		cin >> x;
		for(int i = 1; i <= 32000; i++) {
			if(i * i >= x) {
				n = i; 	
				break;
			}
		}
		if(x <= n * n - n + 1)
			cout << x - (n - 1) * (n - 1) << " " << n << endl;
		else
			cout << n << " " << n - (x - (n * n - n + 1)) << endl;
	}
	return 0;
}

D

题意

根据题中的规则进行操作,求将给定数变为一个\(2\)的任意次幂的最少操作数。

思路

看数据范围,可以知道我们最多只需预处理到\(10^{18}\),在这个上限以内符合条件的数在\(60\)个左右,我们是可以接受的。

所以可以进行枚举,找到最小的答案。

答案怎么算?其实就是一个双指针的操作。遇到相同的统计一下\((++cnt)\),一起移动指针,否则只移动题中所给的字符串的指针,直到遍历完其中一个字符串。操作次数也就很好算了,等效为把原字符串中与答案不同的先删掉\(+\)答案有但原字符串没有的。

#include <bits/stdc++.h>
const int N = 100;
const int INF = 1 << 30;
typedef long long ll;
using namespace std;
int k, ans;
ll bin[N];
string s;
int calc(ll x) {
	string t = "";
	while(x) {
		t += (x % 10) + '0';
		x /= 10;
	}
	reverse(t.begin(), t.end());
	int cnt = 0, j = 0, l = 0;
	while(j < s.length() && l < t.length()){
		if(s[j] == t[l]) {
			++cnt;
			j++;
			l++;
		}
		else j++;
	}
	return s.length() + t.length() - cnt * 2;
}
int main() {
	ios::sync_with_stdio(false);
	cin >> k;
	bin[0] = 1;
	for(int i = 1; i <= 62; i++) bin[i] = bin[i - 1] * 2;
	while(k--) {
		ans = INF;
		cin >> s;
		for(int i = 0; i <= 62; i++) ans = min(ans, calc(bin[i]));
		cout << ans << endl;
	}
	return 0;
}

F1

题意

给定数\(x,k(k \in [1,2])\),找到最小的\(y\),使得\(y \leq x\)并且保证\(y\)的十进制表示中最多出现\(k\)种数字。

思路

这题要想分类讨论还是太难了......

若\(k=1\),则可以通过枚举找到答案。

若\(k=2\),我们可以枚举确定答案是由哪两个数字组成,同时按贪心思路构造出较小的答案,进行统计。很难想。

#include <bits/stdc++.h>
using namespace std;
int t, k;
set<char> o;
string s;
string calc(char x) {
	string y = "";
	for(int i = 0; i < s.length(); i++) y += x;
	return y;
}
void solve1() {
	for(char i = '0'; i <= '9'; i++) {
		string t = calc(i);
		if(t > s) {
			cout << t << endl;
			return ;
		}
	}
}
void solve2() {
	string t = calc('9');
	for(char i = '0'; i <= '9'; i++) {
		for(char j = i + 1; j <= '9'; j++) {
			for(int l = 0; l < s.length(); l++) {
				if(s[l] < j) {
					string g = s;
					g[l] < i ? g[l] = i : g[l] = j;
					for(int p = l + 1; p < g.length(); p++) g[p] = i;
					if(t > g) t = g;
				}
				if(s[l] != i && s[l] != j) break;
			}
		}
	}
	cout << t << endl;
}
int main() {
	ios::sync_with_stdio(false);
	cin >> t;
	while(t--) {
		o.clear();
		cin >> s >> k;
		for(int i = 0; i < s.length(); i++) o.insert(s[i]);
		if(o.size() <= k) {
			cout << s << endl;
			continue;
		}
		k == 1 ? solve1() : solve2();
	}
	return 0;
}

还有个超时的做法,就是\(k=2\)时用\(dfs\)来做,也贴在这里吧......

#include <bits/stdc++.h>
using namespace std;
int t, k;
set<char> o;
string s;
string calc(char x) {
	string y = "";
	for(int i = 0; i < s.length(); i++) y += x;
	return y;
}
void solve1() {
	for(char i = '0'; i <= '9'; i++) {
		string t = calc(i);
		if(t > s) {
			cout << t << endl;
			return ;
		}
	}
}
void dfs(int step, char t1, char t2, string &t, string p) {
	//cout << t << " " << p << endl;
	if(step == 2 && p == "0")
		return ;
	if(step != 1 && p[0] < s[0])
		return ;
	if(step == s.length() + 1) {
		if(p < t && p > s) {
			t = p;
			return ;
		}
		return ;
	}
	string last = p;
	dfs(step + 1, t1, t2, t, p + t1);
	p = last;
	dfs(step + 1, t1, t2, t, p + t2);
	p = last;
}
void solve2() {
	string t = "", p = "";
	t = calc('9');
	for(char i = '0'; i <= '9'; i++) {
		for(char j = '0'; j <= '9'; j++) {
			if(i == j)
				continue;
		//	cout << *it1 << " " << *it2 << endl;
			dfs(1, i, j, t, p);
		}
	}
	cout << t << endl;
}
int main() {
	ios::sync_with_stdio(false);
	cin >> t;
	while(t--) {
		o.clear();
		cin >> s >> k;
		for(int i = 0; i < s.length(); i++) o.insert(s[i]);
		if(o.size() <= k) {
			cout << s << endl;
			continue;
		}
		k == 1 ? solve1() : solve2();
	}
	return 0;
}
上一篇:phaser3入门教程-从零开始开发一个打砖块游戏


下一篇:Havok Physics 2012(1)