Codeforces Round #620 (Div. 2)解题报告

Codeforces Round #620 (Div. 2)

【A.Two Rabbits】

【题目描述】
水题,给你一维坐标x和y,y > x,每次y - b,x + a,问x和y能否相遇

【解题思路】
x + ta = y - tb
t = (y - x) / (a + b)
那么相遇的条件是(y - x) % (a + b) == 0

【AC代码】

#include 
using namespace std;
#define endl '\n'
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	int t;
	cin >> t;
	while (t--) {
		int x, y, a, b;
		cin >> x >> y >> a >> b;
		if ((y - x) % (a + b)) cout << "-1" << endl;
		else cout << (y - x) / (a + b) << endl;
	}
	return 0;
}

【B.Longest Palindrome】

【题目描述】
给你n个字符串,问你这n个字符串能组成的最大回文串长度是多少

【解题思路】
可以用map或者set标记每个字符串,然后O(n)遍历所有字符串O(logn)查看是否有与其相反的字符串,如果有就将其加入到答案字符串

注意有可能其本身为回文串,那么我们可以考虑将所有本身即为回文串的字符串加入到答案中间

【AC代码】

#include 
using namespace std;
#define endl '\n'
string s[110];
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	register int n, m;
	register map<string, int> mp;
	cin >> n >> m;
	for (int i = 1; i <= n; ++i) {
		cin >> s[i];
		++mp[s[i]];
	}
	register string ans = "";
	register string aans = "";
	for (int i = 1; i <= n; ++i) {
		register string p = s[i];
		reverse(p.begin(), p.end());
		if (mp[p]) {
			if (p == s[i]) {
				if (p.length() > aans.length())
					aans = p;
			}
			else ans += s[i];
			--mp[s[i]];
		}
	}
	register string p = ans;
	p += aans;
	reverse(ans.begin(), ans.end());
	p += ans;
	cout << p.length() << endl;
	cout << p << endl;
	return 0;
}

【C.Air Conditioner】

【题目描述】
有一间餐馆初始温度为m,有n个客人即将到达餐馆就餐,每个人的属性有到达时间t和适宜温度区间[a, b],每分钟你可以选择将餐馆的温度上升1或下降1或不变,问你能否满足所有客人的适宜温度区间

【解题思路】
根据每位客人的到达时间差值不断修改下一位客人到达时餐馆的温度范围,当客人的区间不在温度范围内即为不可能

【AC代码】

#include 
using namespace std;
#define endl '\n'
struct Node {
	int t, a, b;
	inline bool operator < (const Node& b)const {
		if (t == b.t) return a < b.a;
		return t < b.t;
	}
}a[110];
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	int t;
	cin >> t;
	while (t--) {
		int n, m;
		cin >> n >> m;
		for (int i = 1; i <= n; ++i) {
			cin >> a[i].t >> a[i].a >> a[i].b;
		}
		sort(a + 1, a + n + 1);
		a[0].t = 0, a[0].a = a[0].b = m;
		int i = 1;
		for (; i <= n; ++i) {
			int temp = a[i].t - a[i - 1].t;
			if (a[i].a > a[i - 1].b) {
				if (temp < a[i].a - a[i - 1].b) break;
			}
			else if (a[i].b < a[i - 1].a) {
				if (temp < a[i - 1].a - a[i].b) break;
			}
			a[i].a = max(a[i - 1].a - temp, a[i].a);
			a[i].b = min(a[i - 1].b + temp, a[i].b);
		}
		if (i > n) cout << "YES" << endl;
		else cout << "NO" << endl;
	}
	return 0;
}

【D.Shortest and Longest LIS】

【题目描述】
有一个长为n - 1的字符串,由‘<’ 和 ‘>’符号组成,请你依据字符串所代表的大小关系构造1 - n的两个序列,第一个保证其LIS最小,第二个LIS最大

LIS:最长递增子序列

【解题思路】
对于第一个数组,我们考虑尽可能将大的数字放在前面,那么其依赖于’<‘号的数目,即每遇到连续的’<‘号我们从后往前输出
对于第二个数组,我们竟可能将小的数字放在前面,依赖于’>‘号的数目,即每遇到连续的’>'号我们从前往后输出

具体参考代码理解

【AC代码】

#include 
using namespace std;
#define endl '\n'
int main() {
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	int t;
	cin >> t;
	while (t--) {
		int n;
		string s;
		cin >> n >> s;
		s = " " + s;
		int l = 1;
		while (l <= n) {
			int ll = l;
			while (ll < n && s[ll] == '<') ++ll;
			for (int i = n - ll + 1; i <= n - l + 1; ++i) cout << i << " ";
			l = ll + 1;
		}
		cout << endl;
		l = 1;
		while (l <= n) {
			int ll = l;
			while (ll < n && s[ll] == '>') ++ll;
			for (int i = ll; i >= l; --i) cout << i << " ";
			l = ll + 1;
		}
		cout << endl;
	}
	return 0;
}

你可能感兴趣的:(codeforces)