zoukankan      html  css  js  c++  java
  • Codeforces Round #706 (Div. 2) A B C

    完整题单

    仍然只过了三题,但是速度慢了,肯定掉分了.

    ABC的思维能力总是够的,但是不够快,准.

    这次的B上手就用模拟,其实稍微想一下就发现会TLE,直到做完了C再看才发现需要特判剪枝.

    不很常用的数据结构复杂度(map,set之类)也不清楚,甚至写到一半去百度了.

    最后B还是得打草稿找规律,可能除了A题最好都要写写画画.

    中途还去看了D,其实不如把这个时间花在B上面,经验表明自己正常情况下总是有能力做出B的.

    不好总结,多练练吧,简单题还是太慢了.

    A

    很容易发现R(a2)+R(a1)=R(a1+a2),那么可以简化为s=a1+a2+R(a1),则只需判断是否存在长度不小于k的字符串a1即可.

    注意判断一下s长度为偶数的情况,处理好细节.

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <string>
    using namespace std;
    
    int n, k;
    string s;
    
    void solve(){
        scanf("%d%d", &n, &k);
        cin >> s;
    
        int pl = 0, pr = n - 1;
        while(s[pl] == s[pr] && pl < pr){pl++, pr--;}
    
        if(pl == 0 && k == 0) {puts("YES");return;}
        if(n & 1)
            if(k <= pl) puts("YES");
            else puts("NO");
        else
            if(k < pl) puts("YES");
            else puts("NO");
    }
    
    int main(){
        int t;
        scanf("%d", &t);
        while(t--) solve();   
    
        return 0;
    }
    A

    B

    使用unordered_map记录数字(因为达到了1e9)是否已经存在,每当把一个原先不存在的数字标记为存在时将答案加一.

    现在注意这样一个现象:n<=1e5,k<=1e9.

    k在极端情况下直接使得模拟超时,说明你得找点歪路子.

    假设集合进行去重升序排序,会发现,max为最右端元素,且mex在一个其左侧的位置,一般情况下期望他和max相距比较远.

    现在把(max+mex)/2向上取整加入到这个序列中,很容易达成一种情况:max没有改变,mex也没有改变.一旦进入这种状态,之后不论进行多少次操作都不再对结果造成影响,此时break即可.

    再仔细想一想,可知上述情况发生只需要在mex位于max左侧就可以了.

    此外还有mex位于max右侧且相邻的情况,比如样例的{0,1,2}.这是一种很特殊的情况,容易看出来此后每次操作都一定会增加一个递增的新元素,所以只需要把答案加上剩下的操作数即可.

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <map>
    #include <unordered_map>
    using namespace std;
    
    unordered_map<int, int> m;  // val, ct
    int n, k;
    
    void solve() {
        m.clear();
        int ans = 0;
        int b = 0, a = 0;  // a - mex, b - max
        scanf("%d%d", &n, &k);
        for (int i = 1; i <= n; i++) {
            int x;
            scanf("%d", &x);
            b = max(b, x);
            ans++;
            m[x]++;
        }
        for (int i = 0; i <= b + 1; i++)
            if (m[i] == 0) {
                a = i;
                break;
            }
    
        int last = -1;
        while (k--) {
            int x = (a + b - 1) / 2 + 1;
            if(x == last) break;
            else if(a == b + 1){
                ans += k + 1;
                break;
            }
            if (m[x] == 0) ans++;
            m[x]++;
            b = max(b, x);
            while (m[a] != 0) a++;
            last = x;
        }
    
        printf("%d
    ", ans);
    }
    
    int main() {
        int t;
        scanf("%d", &t);
        while (t--) solve();
    
        return 0;
    }
    B

    C

    这题比较有意思,证明猜想之后实现很简单.

    注意到数值的符号并不会造成影响,所以干脆把所有点都移到其对应的正半轴上,现在任意矿工与任意钻石之间的连线都位于第一象限.

    会自然而然地认为,不停地让截距最小的矿工取走截距最小的钻石可以得最优解,可以得到如下证明:

    假设有矿工位于a1,a2,钻石位于b1,b2,如图,红线表示(a1,b1),(a2,b2)的组合,绿线表示(a2,b1),(a1,b2)的组合:

     

     会发现红绿线构成了两个对顶的三角形,如果运用"三角形两边之和大于第三边"的定理,可得绿线长度之和大于红线.

     这意味着一旦某些组合之间发生了交叉(绿线),那么总是可以交换他们来消除交叉(红线),这就粗略地证明了猜想的正确性.

    这样做确实就AC了.

    #include <algorithm>
    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <cmath>
    using namespace std;
    
    int n;
    double x[100010], y[100010];
    
    double calc(double x, double y){
        return sqrt(x * x + y * y);
    }
    
    void solve(){
        int p1 = 0, p2 = 0;
        scanf("%d", &n);
        for(int i = 1; i <= 2 * n; i++){
            double a, b;
            scanf("%lf%lf", &a, &b);
            if(a == 0) y[++p2] = fabs(b);
            else x[++p1] = fabs(a);
        }
        sort(x + 1, x + 1 + n);
        sort(y + 1, y + 1 + n);
        double ans = 0;
        for(int i = 1; i <= n; i++)
            ans += calc(x[i], y[i]);
        printf("%.10f
    ", ans);
    }
    
    int main(){
        int t;
        scanf("%d", &t);
        while(t--) solve();   
    
        return 0;
    }
    C

    经常羡慕十几场就上橙红的人,我也打了十几局了,发现上蓝也没想象得那么容易.

    不过有的人是有基础的,理所当然上分快,而另一些人上分比你还慢得多.

    也看到一个在我前面几名的蓝名,掉了60分.

    有句话说不要怕掉分,不停打就行了.

    毕竟蓝名也会掉分,我这又算什么呢.

  • 相关阅读:
    开启MySQL远程访问权限 允许远程连接
    [SCOI2005]互不侵犯
    树的数据生成器
    博客园优化
    图的随机数据生成器
    CF 983B 序列函数
    [HNOI2010]弹飞绵羊
    luogu P3393 逃离僵尸岛
    LCT解读(1)
    [APIO2010]特别行动队
  • 原文地址:https://www.cnblogs.com/Gaomez/p/14514958.html
Copyright © 2011-2022 走看看