Codeforces Round #706 (Div. 2)A-D

Codeforces Round #706 (Div. 2)

很奇怪的一场,速切完ABC遇到D题看了半天看不懂。D研究了半天看了会EF发现可作,结果wa了,又回来看D,仍是把本身绕进去。今天补题的时候秒切D(((。
仍是功力不够。node

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\)的转置。c++

其实就是统计知足回文条件的字符的数目,若大于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

给了两个函数:spa

  1. 一个是max(集合),得到集合中最大的数。
  2. 一个是mex(集合),得到集合中最小的没出现过的数

(为方便表述,如下max与mex均表示集合中的对应元素。)
给定集合和操做次数k,要求每次操做在集合中加入元素\(\lceil \frac{max+mex}{2}\rceil\)
观察可得:code

  1. 若mex> max,则每次操做都会增长一个元素
  2. 若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轴上一点配对,求距离的最小值。
切比雪夫定理的直接应用。贪心便可。ci

#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先走,求谁赢。
本质是披着博弈壳子的模拟题。get

分析:string

  1. Q不可能走两边和半山腰,由于D能够在Q的左右两边的位置把他堵死。
  2. Q一定选择最高的山(咱们把山的高度定义为山的左右落差的最大值)(最高的山能走下来的路最大)。
  3. 最高的山不能有两座,若是有两座,Q选择其中一座则D能够从另外一座的山脚往上走。
  4. 最高的山的高度必须是偶数(咱们暂且把135这样的山的高度当作是2),这样当Q在‘5’,D在‘1’时,Q必赢
  5. 最高的山左右两边的高度必须相等。
#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");
}
相关文章
相关标签/搜索