• Codeforces Round #618 (Div. 2)


    A. Non-zero (CF 1300 A)

    题目大意

    给定(n)个数。有一种操作,选择一个数使之加一。现要求这(n)个数的和和积均不为0,问最少的操作次数。

    解题思路

    (0)(1),最后和为(0)的话,因为每个数都不是(0),所以必有正也有负,此时再随便找一个正数加(1)即可。

    神奇的代码
    #include <bits/stdc++.h>
    #define MIN(a,b) ((((a)<(b)?(a):(b))))
    #define MAX(a,b) ((((a)>(b)?(a):(b))))
    #define ABS(a) ((((a)>0?(a):-(a))))
    using namespace std;
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<PII> VPII;
    typedef vector<LL> VL;
    typedef pair<LL,LL> PLL;
    typedef vector<PLL> VPLL;
    
    template <typename T>
    void read(T &x) {
        int s = 0, c = getchar();
        x = 0;
        while (isspace(c)) c = getchar();
        if (c == 45) s = 1, c = getchar();
        while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
        if (s) x = -x;
    }
    
    template <typename T>
    void write(T x, char c = ' ') {
        int b[40], l = 0;
        if (x < 0) putchar(45), x = -x;
        while (x > 0) b[l++] = x % 10, x /= 10;
        if (!l) putchar(48);
        while (l) putchar(b[--l] | 48);
        putchar(c);
    }
    
    int main(void) {
        int kase; read(kase);
        for (int i = 1; i <= kase; i++) {
            int n;
            read(n);
            int a[n+1]={0};
            int sum=0;
            int ans=0;
            for(int i=1;i<=n;++i){
                read(a[i]);
                if (a[i]==0) ++a[i],++ans;
                sum+=a[i];
            }
            if (sum==0) ++ans;
            write(ans,'
    ');
        }
        return 0;
    }
    


    B. Assigning to Classes (CF 1300 B)

    题目大意

    (2*n)个数要求分成两组,使两个组的中位数相差最小,问最小差。

    解题思路

    很容易看出答案就是这(2*n)个数排好序后第(n)个数和第(n+1)个数的差值。

    神奇的代码
    #include <bits/stdc++.h>
    #define MIN(a,b) ((((a)<(b)?(a):(b))))
    #define MAX(a,b) ((((a)>(b)?(a):(b))))
    #define ABS(a) ((((a)>0?(a):-(a))))
    using namespace std;
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<PII> VPII;
    typedef vector<LL> VL;
    typedef pair<LL,LL> PLL;
    typedef vector<PLL> VPLL;
    
    template <typename T>
    void read(T &x) {
        int s = 0, c = getchar();
        x = 0;
        while (isspace(c)) c = getchar();
        if (c == 45) s = 1, c = getchar();
        while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
        if (s) x = -x;
    }
    
    template <typename T>
    void write(T x, char c = ' ') {
        int b[40], l = 0;
        if (x < 0) putchar(45), x = -x;
        while (x > 0) b[l++] = x % 10, x /= 10;
        if (!l) putchar(48);
        while (l) putchar(b[--l] | 48);
        putchar(c);
    }
    
    int main(void) {
        int kase; read(kase);
        for (int i = 1; i <= kase; i++) {
           int n;
           read(n);
           n<<=1;
           int a[n];
           for(int i=0;i<n;++i) read(a[i]);
           sort(a,a+n);
           int ans=a[n/2]-a[n/2-1];
           write(ans,'
    ');
        }
        return 0;
    }
    


    C. Anu Has a Function (CF 1300 C)

    题目大意

    有一函数(f:f(x, y) = (x | y) - y)(|)是或运算并不是整除),现有(n)个数(a_1,a_2,...,a_n),要求安排一种顺序,使得(f(f(dots f(f(a_i, a_j), a_k), dots a_{z}), a_n))结果最大。

    解题思路

    注意到(f)函数可以等效为一种位运算,(f(x,y)),对于(y)的每一个是(1)的位,如果(x)对应位为(1)则变成(0),否则则不改变。所以一旦我们确定了第一个数(a_i),剩下的数的顺序是无关紧要的。我们统计每个数在二进制下(1)所在的位数,最后从高到低看哪一位的(1)只有一个数有,就把那个数放在第一位,其他的数随便输出就好了。因为如果出现次数是(2)及以上的话会被消掉。

    神奇的代码
    #include <bits/stdc++.h>
    #define MIN(a,b) ((((a)<(b)?(a):(b))))
    #define MAX(a,b) ((((a)>(b)?(a):(b))))
    #define ABS(a) ((((a)>0?(a):-(a))))
    using namespace std;
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<PII> VPII;
    typedef vector<LL> VL;
    typedef pair<LL,LL> PLL;
    typedef vector<PLL> VPLL;
    
    template <typename T>
    void read(T &x) {
        int s = 0, c = getchar();
        x = 0;
        while (isspace(c)) c = getchar();
        if (c == 45) s = 1, c = getchar();
        while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
        if (s) x = -x;
    }
    
    template <typename T>
    void write(T x, char c = ' ') {
        int b[40], l = 0;
        if (x < 0) putchar(45), x = -x;
        while (x > 0) b[l++] = x % 10, x /= 10;
        if (!l) putchar(48);
        while (l) putchar(b[--l] | 48);
        putchar(c);
    }
    
    int main(void) {
        int n;
        read(n);
        int a[n];
        int cnt[35];
        memset(cnt,0,sizeof(cnt));
        for(int i=0;i<n;++i) {
            read(a[i]);
            int qwq=a[i];
            int id=0;
            while(qwq){
                cnt[id++]+=(qwq&1);
                qwq>>=1;
            }
        }
        int id=35;
        while(id>=0&&cnt[id]!=1) --id;
        if (id==-1) for(int i=0;i<n;++i) printf("%d%c",a[i],i==n-1?'
    ':' ');
        else{
            for(int i=0;i<n;++i) if ((a[i]>>id)&1){id=i;break;}
            printf("%d ",a[id]);
            for(int i=0;i<n;++i) if (i==id) continue; else printf("%d ",a[i]);
        }
        return 0;
    }
    


    D. Aerodynamic (CF 1300 D)

    题目大意

    以给端点坐标的形式给定一个多凸边形(P),定义一种线性变换(P(x,y))表示将多边形(P)分别沿(x)轴方向平移(x)个单位,沿(y)轴方向平移(y)个单位后的多边形。定义(T)是一连串符合条件的(P(x,y))多边形的并集,条件是原点((0,0))(P(x,y))的边上或里面,问(T)(P)是否相似。

    解题思路

    读题读了好多遍才明白……原本没有什么头绪的然后我打开几何画板把样例三的图形画出来后。
    多边形
    我有一个大胆的想法。
    如果是奇多边形肯定不相似,偶多边形的话,就看它对边是否平行且相等。(点(i)与点(i+1)所形成的边与点(i+frac{n}{2})与点(i+1+frac{n}{2})所形成的边)
    (猜题大法好)

    神奇的代码
    #include <bits/stdc++.h>
    #define MIN(a,b) ((((a)<(b)?(a):(b))))
    #define MAX(a,b) ((((a)>(b)?(a):(b))))
    #define ABS(a) ((((a)>0?(a):-(a))))
    using namespace std;
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<PII> VPII;
    typedef vector<LL> VL;
    typedef pair<LL,LL> PLL;
    typedef vector<PLL> VPLL;
    
    template <typename T>
    void read(T &x) {
        int s = 0, c = getchar();
        x = 0;
        while (isspace(c)) c = getchar();
        if (c == 45) s = 1, c = getchar();
        while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
        if (s) x = -x;
    }
    
    template <typename T>
    void write(T x, char c = ' ') {
        int b[40], l = 0;
        if (x < 0) putchar(45), x = -x;
        while (x > 0) b[l++] = x % 10, x /= 10;
        if (!l) putchar(48);
        while (l) putchar(b[--l] | 48);
        putchar(c);
    }
    
    int main(void) {
        int n;
        read(n);
        pair<int,int> point[n];
        for(int x,y,i=0;i<n;++i){
            read(x);
            read(y);
            point[i]=make_pair(x,y);
        }
        if (n&1) puts("NO");
        else{
            bool qwq=true;
            for(int j=0,i=n/2;i<n;++i,++j){
                if (!qwq) break;
                if (point[j].first-point[j+1].first!=point[(i+1)%n].first-point[i].first) qwq=false;
                if (point[j].second-point[j+1].second!=point[(i+1)%n].second-point[i].second) qwq=false;
            }
            if (qwq) puts("YES");
            else puts("NO");
        }
        return 0;
    }
    


    E. Water Balance (CF 1300 E)

    题目大意

    给定一个有(n)个数的序列,有一种操作,选择两个数(l,r(l<r)),然后将区间([l,r])的数替换成这个区间的平均数。可以进行任意多次操作,问最后能得到的字典序最小的序列是怎样的。

    解题思路

    我们注意到一个重要性质:最终序列的数一定是递增的。因为如果有前一个数大于后一个数,那么我们把那个范围取个平均值,得到的是一个字典序更小的序列。所以我们就从左到右依次把每个数添加进去,如果这个数小于前一个我们已经平均的平均数,那么我们就把这个数也加入到前一个平均的范围内,重复即可。

    神奇的代码
    #include <bits/stdc++.h>
    #define MIN(a,b) ((((a)<(b)?(a):(b))))
    #define MAX(a,b) ((((a)>(b)?(a):(b))))
    #define ABS(a) ((((a)>0?(a):-(a))))
    using namespace std;
    typedef long long LL;
    typedef vector<int> VI;
    typedef pair<int,int> PII;
    typedef vector<PII> VPII;
    typedef vector<LL> VL;
    typedef pair<LL,LL> PLL;
    typedef vector<PLL> VPLL;
    
    template <typename T>
    void read(T &x) {
        int s = 0, c = getchar();
        x = 0;
        while (isspace(c)) c = getchar();
        if (c == 45) s = 1, c = getchar();
        while (isdigit(c)) x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
        if (s) x = -x;
    }
    
    template <typename T>
    void write(T x, char c = ' ') {
        int b[40], l = 0;
        if (x < 0) putchar(45), x = -x;
        while (x > 0) b[l++] = x % 10, x /= 10;
        if (!l) putchar(48);
        while (l) putchar(b[--l] | 48);
        putchar(c);
    }
    
    int main(void) {
        int n;
        read(n);
        LL a[n+1]={0};
        for(int i=1;i<=n;++i) read(a[i]);
        pair<pair<LL,LL>,int> qwq[n+1];
        int cnt=0;
        qwq[0]=(make_pair(make_pair(a[1],1),1));
        for(int i=2;i<=n;++i){
            if (qwq[cnt].first.first>=(LL)qwq[cnt].first.second*a[i]){
                qwq[cnt]=make_pair(make_pair(qwq[cnt].first.first+a[i],qwq[cnt].first.second+1),i);
                while(cnt>0&&qwq[cnt].first.first*qwq[cnt-1].first.second<=qwq[cnt-1].first.first*qwq[cnt].first.second) qwq[cnt-1]=make_pair(make_pair(qwq[cnt].first.first+qwq[cnt-1].first.first,qwq[cnt].first.second+qwq[cnt-1].first.second),qwq[cnt].second),--cnt;
            }
            else qwq[++cnt]=make_pair(make_pair(a[i],1),i);
        }
        cnt=0;
        for(int i=1;i<=n;++i){
            printf("%.9f
    ",(double)qwq[cnt].first.first/(double)qwq[cnt].first.second);
            if (qwq[cnt].second==i) ++cnt;
        }
        return 0;
    }
    


  • 相关阅读:
    2019 SDN上机第7次作业
    第01组 Beta冲刺(4/5)
    第01组 Beta冲刺(3/5)
    第01组 Beta冲刺(2/5)
    第01组 Beta冲刺(1/5)
    2019 SDN上机第6次作业
    2019 SDN上机第5次作业
    SDN课程阅读作业(2)
    第01组 Alpha事后诸葛亮
    第01组 Alpha冲刺(6/6)
  • 原文地址:https://www.cnblogs.com/Lanly/p/12292092.html
Copyright © 2020-2023  润新知