很奇怪的一场,速切完ABC遇到D题看了半天看不懂。D研究了半天看了会EF发现可做,结果wa了,又回来看D,还是把自己绕进去。今天补题的时候秒切D(((。
还是功力不够。
给定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");
}
}
给了两个函数:
(为方便表述,以下max与mex均表示集合中的对应元素。)
给定集合和操作次数k,要求每次操作在集合中加入元素\(\lceil \frac{max+mex}{2}\rceil\)
观察可得:
#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();
}
}
大意就是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();
}
}
最麻烦的一题,其实补题完之后发现还好。
给定一串整数,表示高度。看作山。
有连绵起伏的山,Q只会下山,D只会上山,Q和D不能相撞,谁没路走谁输,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");
}
Codeforces Round #706 (Div. 2)A-D
原文:https://www.cnblogs.com/clo91eaf/p/14520591.html