• 2020/5/8—cf,我裂开来


    呜呜呜我爆零了呜呜呜ljll

    嗯T1T2防爆零的没了呜呜呜
    在此纪念可怜的yjz大佬21发AC

     太惨了(逃

    先来说说我们都有些啥题目吧。。。


    T1

    嗯,裂开了,当场裂开
    我一看!桶排!
    然后实现,嗯?嗯!嗯???不对啊,这怎么搞???

     第一发

    嗯!输出错了!改!

    第二发

    我%^&*()_)(*&^

    嗯。。。
    我先调一调awa
    嗯!找到了!估计能A了!

     这wtm。。。

    开T2吧。。。

    T2

    嗯!大水题!

    但是,我仔细一看!

    正好n个?????
    这。。。
    瞬间就想到了一个不需要证明的贪心。。。
    然后。。。

    标准结局

    我太难了
    仔细一想,发现排个序就好了。。。
    然后又调了亿调,就在比赛结束后一分钟的时候A了

    这tm的。。。
    我接下来看了看T3。。。

     就是一个dp。。。(第一想法)
    这。。。
    不行啊。

    那就试试建图!2-sat!(第二想法)
    这条件!我吐了,根本不行。。。
    第三想法:炸了
    然后一想。。。这绝对是个dp。。。
    推了推式子,没搞出来。。。
    这就是全部的心路历程。。。
    我太难了 唉,开始写正解
    T1

    其实吧,就是一个排序能解决的事情,但是因为那个k的迷惑,我傻了。
    想想排序,其实只要保证每一个字典序的接近就能找到最大值中的最小值了

    直接构造 其实就是个贪心。。。
    排个序

    来自oi-wiki 这就是排序贪心的常见的情况之一

    第一种情况

    如果s[1]==s[k]

    排序完了就能发现这个k与1之间是有联系的,只要他们不相同,因为排序的原因,就能够直接的说明在大的字符串就是s[k]。
    问为什么的话,其实就是因为如果我在一个字符串中放这个字符,或者是将一类的字符放到其他的k个字符串中,易证,这个一定是可以在这种情况中最大的。
    然后是另一种情况。


    如果s[k+1]!=s[n]

    那么在这种情况下,k个字符串中的第一个字符都是一样的。字典序的大小完全在于后面的字符串
    为了保证这是一个最大的字符串,我不得不把下一个字符放在这个字符串上面。
    只有这样,才能保证这个是最大中的最小。为了最大,我们一定要在他的后面加入一个字符,但是为了最小,又只能加入全部的字符。
    比如对于

    5 2
    baacb

     这个样例就是这种情况。排序完是aabbc,最终的答案是abbc。
     最开始,我很疑惑。。。因为我觉得abc<abbc,然后我就傻了。。。
     但是在这种情况中,因为必须加入一个字符并最小,所以就会选择加入s[k+1].
      这个是很显然的。但是,之后为了使它继续保持在最大的情况下,我们不得不把全部比第一个字符大的字符加入它。
     因为如果有一个字符串得到了之后的字符,它就不会再这种情况中继续保持最大了。像abb和ac,ac就会大于abb了。
     因为大的字符越靠前,这个字符串的字典序就会越大,所以我们就要尽可能的把大的字符往后靠,也就是把小的字符往前填。
     所以就可以得到了awa

     第三种情况

     就是s[i]==s[k]&&s[k+1]==s[k]

     那就之间把第一个输出了,然后在选择几个字符输出就好了啊。。。这是最简单的。
     附上代码

     

    #include<bits/stdc++.h>
    #define ll long long
    using namespace std;
    char s[1000001];
    int k,n,T; 
    inline ll read()
    {
        char c=getchar();ll a=0,b=1;
        for(;c<'0'||c>'9';c=getchar())if(c=='-')b=-1;
        for(;c>='0'&&c<='9';c=getchar())a=a*10+c-48;
        return a*b;
    }
    int main()
    {
    //    freopen(".in","r",stdin);
    //    freopen(".out","w",stdout);
        T=read();
        while(T--)
        {
            cin>>n>>k;
            scanf("%s",s+1);
            sort(s+1,s+n+1);
            if(s[k]!=s[1])
            {
                printf("%c
    ",s[k]);
            }
            else
            if(s[n]!=s[k+1])
            {
                printf("%c%s
    ",s[1],s+k+1);
            }
            else
            {
                cout<<s[1];
                for(int i=1;i<=(n-1)/k;i++)
                {
                    printf("%c",s[k+1]);
                }
                cout<<endl;
            }
        }
        return 0;
    }

    就是这么简单

    T2

     一看T2,无解输出-1,嗯,要记得,嗯。
    然鹅!根本就没有无解的情况。。。极其可怕awa,来自cf的一波误导awa

    转载于luogu的题解

    要达到最少次数,贪心的想每次肯定加上最多的量 x * 2,然而每次最少加上变化过的x,所以最后一次加的数可能小于当前的x,但是没关系,可以让这次加上的那个小于x的数尽可能的往前移直到前一个数小于等于它,然后按照顺序求一遍答案即可。

    这题比T1简单。。。
    溜了,附上代码

    void solve() {
        int n;
        scanf("%d", &n);
        vector<int> v;
        int x = 1;
        while(n > 0) {
            if(n > x) v.push_back(x);
            else v.push_back(n);
            n -= x;
            x <<= 1;
        }
        sort(v.begin(), v.end());
        printf("%d
    ", v.size() - 1);
        for(int i = 1; i < v.size(); i++) {
            printf("%d ", v[i] - v[i - 1]);
        }
        puts("");
    }

    T2就好了。。

    T3还没写awa

    qwq

  • 相关阅读:
    Cocos2d-x 2.2.3 Android配置
    于ubuntu配置hadoop当问题
    Xenomai 3 和 PREEMPT_RT 有哪些优势相比,
    【安卓注意事项】模仿猎豹清理大师波效应
    JPA实体继承映射
    第26周日许昌夜
    第26周六悲剧许昌夜
    第26黑色周五
    第26周四
    第26周三
  • 原文地址:https://www.cnblogs.com/HLZZPawa/p/12853033.html
Copyright © 2020-2023  润新知