Codeforces Round #706 (Div. 2)A-D
Codeforces Round #706 (Div. 2)
很奇怪的一场,速切完ABC遇到D题看了半天看不懂。D研究了半天看了会EF发现可做,结果wa了,又回来看D,还是把自己绕进去。今天补题的时候秒切D(((。
还是功力不够。
A. Split it!
给定n,k和字符串s,n为字符串s的长度。
问是否存在一系列字符串满足\(s=a_1+a_2+…+a_k+a_{k+1}+R(a_k)+R(a_{k-1})+…+R(a_1).\)
其中\(a_i\)为某一字符串,\(R(a_i)\)是\(a_i\)的转置。
其实就是统计满足回文条件的字符的数目,若大于k则满足条件。
要注意一个小细节,就是\(a_{k+1}\)不能为空字符串,wa*1
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 2e5 + 5;
ll read(){
char ch=getchar();
ll x=0,f=1;
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
return x*f;
}
int solve(){
string s;
ll n = read(), k = read();
cin >> s;
if (k == 0) return 1;
if (n == 2 * k) return 0;
for (int i = 0, j = n - 1; i < j; i++, j--)
{
if (s[i] != s[j])break;
k--;
//cout << k << endl;
}
if (k <= 0) return 1;
else return 0;
}
int main(){
int t;cin>>t;
while(t--){
solve() ? puts("YES") : puts("NO");
}
}
B. Max and Mex
给了两个函数:
- 一个是max(集合),获得集合中最大的数。
- 一个是mex(集合),获得集合中最小的没出现过的数
(为方便表述,以下max与mex均表示集合中的对应元素。)
给定集合和操作次数k,要求每次操作在集合中加入元素\(\lceil \frac{max+mex}{2}\rceil\)
观察可得:
- 若mex> max,则每次操作都会增加一个元素
- 若mex< max,若加入元素已存在,则元素数量不改变,否则增加一个
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 2e5 + 5;
ll read(){
char ch=getchar();
ll x=0,f=1;
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
return x*
void solve(){
ll n = read(), k = read();
ll maxx = 0, temp;
set<ll> s;
map<ll, bool> mp;
for (int i = 1; i <= n; i++) {temp = read(); s.insert(temp); maxx = max(maxx, temp);}
int cnt = 0;
while (s.count(cnt)){cnt++;}
//cout << cnt << endl;
if (cnt >= n) cout << n + k << endl;
else if (k && !s.count((maxx + cnt + 1)/2))
{
cout << n + 1 << endl;
}
else cout << n << endl;
}
int main(){
int t;cin>>t;
while(t--){
solve();
}
}
C. Diamond Miner
大意就是xy坐标轴上分别有n个点,将x轴与y轴上一点配对,求距离的最小值。
切比雪夫定理的直接应用。贪心即可。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 5;
ll read(){
char ch=getchar();
ll x=0,f=1;
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
return x*f;
}
double dis(ll a, ll b)
{
return sqrt(a * a + b * b);
}
void solve(){
ll n = read(), x[maxn], y[maxn];
ll xx, yy;
for (int i = 0, j = 0; i + j < n * 2;)
{
xx = read(), yy = read();
if(xx == 0ll) {y[j] = abs(yy); j++;}
if(yy == 0ll) {x[i] = abs(xx); i++;}
//cout << i << " " << j << endl;
}
sort(x, x + n);
sort(y, y + n);
double ans = 0;
for (int i = 0; i < n; i++)
{
ans += dis(x[i], y[i]);
}
printf("%.10lf\n", ans);
}
int main(){
int t;cin>>t;
while(t--){
solve();
}
}
D. Let's Go Hiking
最麻烦的一题,其实补题完之后发现还好。
给定一串整数,表示高度。看作山。
有连绵起伏的山,Q只会下山,D只会上山,Q和D不能相撞,谁没路走谁输,Q先走,求谁赢。
本质是披着博弈壳子的模拟题。
分析:
- Q不可能走两边和半山腰,因为D可以在Q的左右两边的位置把他堵死。
- Q必定选择最高的山(我们把山的高度定义为山的左右落差的最大值)(最高的山能走下来的路最大)。
- 最高的山不能有两座,如果有两座,Q选择其中一座则D可以从另一座的山脚往上走。
- 最高的山的高度必须是偶数(我们暂且把135这样的山的高度看成是2),这样当Q在‘5’,D在‘1’时,Q必赢
- 最高的山左右两边的高度必须相等。
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 5;
ll read(){
char ch=getchar();
ll x=0,f=1;
while(ch<'0'||ch>'9'){if(ch=='-') f=-1;ch=getchar();}
while(ch>='0'&&ch<='9') x=x*10+(ch^48),ch=getchar();
return x*f;
}
struct node
{
int l, r;
}m[maxn];
bool solve(){
ll n = read(), a[maxn], h[maxn], maxx = 0;
for (int i = 1; i <= n; i++) a[i] = read();
for (int i = 2; i <= n; i++) if (a[i] > a[i-1]) m[i].l = m[i-1].l + 1;
for (int i = n-1; i >= 1; i--) if (a[i] > a[i+1]) m[i].r = m[i+1].r + 1;
// for (int i = 1; i <= n; i++) cout << i << " " << m[i].l << " " << m[i].r << endl;
for (int i = 1; i <= n; i++)
{
h[i] = max(m[i].l, m[i].r);
maxx = max(maxx, h[i]);
}
if (maxx % 2 == 0)
{
int cnt = 0, pos;
for (int i = 1; i <= n; i++)
{
if (h[i] == maxx)
{
pos = i;
cnt++;
}
}
if(cnt > 1)return 0;
if(m[pos].l == m[pos].r) return 1;
return 0;
}
return 0;
}
int main(){
solve() ? puts("1") : puts("0");
}

浙公网安备 33010602011771号