Educational Codeforces Round 157 (Rated for Div. 2)
Dashboard - Educational Codeforces Round 157 (Rated for Div. 2) - Codeforces
A. Treasure Chest
题意:在一条OX坐标轴上,箱子在x处,钥匙在y处,箱子最多可以移动k秒,初始在0点处,一秒移动一个单位,最短时间打开箱子
思路:箱子比钥匙远,拿着钥匙找箱子;箱子比钥匙远,若能把箱子移动到钥匙,则一路带着箱子找钥匙,否则把箱子移动到最大距离,然后跑来回拿钥匙开箱子
AC code:
#include<bits/stdc++.h>
#define endl '\n'
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;
typedef long long LL;
typedef pair<char, int> PCI;
typedef pair<int, int> PII;
const int N = 5e5+10, M = 1001;
const int INF = 0x3f3f3f3f, mod = 998244353;
int T, x, y, k;
int gcd(int a, int b){
if(b) while((a %= b) && (b %= a));
return a + b;
}
int main(){
fast();
T = 1;
cin >> T;
while(T --){
cin >> x >> y >> k;
int ans = 0;
if(x >= y) ans = x;
else{
if(y - x <= k) ans = y;
else{
ans = x + k;
ans += 2 * (y - (x + k));
}
}
cout << ans << endl;
}
return 0;
}
B. Points and Minimum Distance
题意:把2*n个点分成n个坐标,使n个坐标相连的距离最小
思路:排序,双指针分别指向首尾,依次作为xy坐标,保证|x1 - x2| + |y1 - y2| 最小
AC code:
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;
typedef long long LL;
typedef pair<char, int> PCI;
typedef pair<int, int> PII;
const int N = 5e5+10, M = 1001;
const int INF = 0x3f3f3f3f, mod = 998244353;
int T, n, m;
int a[N];
int gcd(int a, int b){
if(b) while((a %= b) && (b %= a));
return a + b;
}
signed main(){
fast();
T = 1;
cin >> T;
while(T --){
cin >> n;
for(int i = 1; i <= 2 * n; i ++)
cin >> a[i];
sort(a + 1, a + 2 * n + 1);
vector<PII> ans;
int l = 1, r = 2 * n;
while(l <= n){
ans.push_back({a[l], a[r]});
l ++, r --;
}
int sum = 0;
for(int i = 1; i < n; i ++){
sum += abs(ans[i].first - ans[i - 1].first) + abs(ans[i].second - ans[i - 1].second);
}
cout << sum << endl;
for(auto i : ans){
cout << i.first << " " << i.second << endl;
}
}
return 0;
}
C. Torn Lucky Ticket
题意: 给出n个由数字组成字符串,定义当一个字符串前缀数字和等于后缀数字和时该字符串为一个幸运字符串,在n个字符串中选择si和sj串进行连接组成新的字符串(i可以等于j,且i+j与j+i为两种),有多少对可以组成幸运字符串
思路:若两个字符串可以组成幸运字符串,则有两种连接可能:
- 首尾相连,两字符串长度以及数字和相同
- 在开始时便用二维map记录每个字符串的长度已经数字和,然后累加记录的情况
- 以前缀字符串或后缀字符串中的某点为分界点,组成的新字符串符合要求,因为字符串最大为5,所以可以枚举分界点进行组合
- 从前往后连接,当分界点的长度大于当前字符串一半时,寻找是否有长度与数字和符合的后缀字符串
- 从后往前连接,将所有字符串反转,重复上述过程
AC code:
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
#define fast() ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;
typedef long long LL;
typedef pair<char, int> PCI;
typedef pair<int, int> PII;
const int N = 5e5+10, M = 1001;
const int INF = 0x3f3f3f3f, mod = 998244353;
int T, n, m;
vector<int> cnt(N, 0);
vector<string> s(N);
map<int, int> mp[M];
int gcd(int a, int b){
if(b) while((a %= b) && (b %= a));
return a + b;
}
signed main(){
fast();
T = 1;
//cin >> T;
while(T --){
cin >> n;
for(int i = 1; i <= n; i ++){
cin >> s[i];
for(auto j : s[i]) cnt[i] += j - '0';
mp[s[i].size()][cnt[i]] ++;
}
int ans = 0, casual = 0;
for(int i = 1; i <= n; i ++)//字符串长度与数字和相同的串
ans += mp[s[i].size()][cnt[i]];
for(int i = 1; i <= n; i ++){//从前往后连接
casual = 0;
for(int j = 0; j < s[i].size() - 1; j ++){
casual += s[i][j] - '0';//枚举前缀分界点长度与大小
if(j + 1 > s[i].size() - (j + 1))
ans += mp[j + 1 - (s[i].size() - (j + 1))][casual - (cnt[i] - casual)];//寻找对应后缀字符串
}
}
for(int i = 1; i <= n; i ++) reverse(s[i].begin(), s[i].end());//反转字符串,反向连接
for(int i = 1; i <= n; i ++){//重复枚举寻找过程
casual = 0;
for(int j = 0; j < s[i].size() - 1; j ++){
casual += s[i][j] - '0';
if(j + 1 > s[i].size() - (j + 1))
ans += mp[j + 1 - (s[i].size() - (j + 1))][casual - (cnt[i] - casual)];
}
}
cout << ans << endl;
}
return 0;
}
/*
_ooOoo_
o8888888o
88" . "88
(| ^_^ |)
O\ = /O
____/`---'\____
.' \\| |// `.
/ \\||| : |||// \
/ _||||| -:- |||||- \
| | \\\ - /// | |
| \_| ''\---/'' | |
\ .-\__ `-` ___/-. /
___`. .' /--.--\ `. . __
."" '< `.___\_<|>_/___.' >'"".
| | : `- \`.;`\ _ /`;.`/ - ` : | |
\ \ `-. \_ __\ /__ _/ .-` / /
======`-.____`-.___\_____/___.-`____.-'======
`=---='
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
佛祖保佑AC,永无bug缠身
*/