Codeforces Round #618 (Div. 2)(A~E)

题目链接

A. Non-zero (水题)

代码

#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <deque>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
#define endl '\n'
#define PI acos(-1)
#define PB push_back
#define ll long long
#define db double
#define INF 1e18
#define mod 998244353
#define lowbit(abcd) (abcd & (-abcd))
#define ios ios::sync_with_stdio(false);
#define fre                          \
{                                    \
    freopen("A.txt", "r", stdin);    \
    freopen("Ans.txt", "w", stdout); \
}

const int mxn = 1e2 + 10;


int ar[mxn];

int main()
{
    /* fre; */
    int T;
    scanf("%d", &T);
    while(T --)
    {
        int n;
        scanf("%d", &n);
        int s1 = 0, s2 = 0;
        int ct = 0;
        for(int i = 1; i <= n; i ++)
        {
            scanf("%d", &ar[i]);
            if(ar[i] == 0)
            {
                ct ++;
                s1 += 1;
            }
            else if(ar[i] > 0)
            {
                s1 += ar[i];
            }
            else
            {
                s2 -= ar[i];
            }
        }

        if(s1 != s2)
            printf("%d\n", ct);
        else
            printf("%d\n", ct + 1);
    }

    return 0;
}

B. Assigning to Classes(水题)

直接看代码吧

分析

  • 题意

  • 思路

代码

#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <deque>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
#define endl '\n'
#define PI acos(-1)
#define PB push_back
#define ll long long
#define db double
#define INF 1e18
#define mod 998244353
#define lowbit(abcd) (abcd & (-abcd))
#define ios ios::sync_with_stdio(false);
#define fre                          \
{                                    \
    freopen("A.txt", "r", stdin);    \
    freopen("Ans.txt", "w", stdout); \
}

const int mxn = 2e5 + 10;
int ar[mxn];

int main()
{
    /* fre; */
    int T;
    scanf("%d", &T);
    while(T --)
    {
        int n;
        scanf("%d", &n);
        for(int i = 1; i <= 2 * n; i ++)
        {
            scanf("%d", &ar[i]);
        }
        sort(ar + 1, ar + 1 + 2 * n);
        /* for(int i = 1; i <= 2 * n; i ++) */
        /*     printf("%d ", ar[i]); */
        int val = ar[(2*n - 1)/2 + 2] - ar[(2*n - 1)/2 + 1];
        printf("%d\n", val);
    }

    return 0;
}


C. Anu Has a Function

分析

  • 题意
  1. 定义 f ( a , b ) = ( a b ) b f(a,b)=(a|b)-b ,翻译一下就是 f ( x , y ) f(x,y) 在x,y对应的二进制位下:1与0对应1、1与1对应0、0与0对应0、0对1对应0,这个定义相当于定义了一种新的二进制运算
  2. 之后又给我了我们一个序列 a [ n ] a[n] ,问通过重新安排ar[n]中元素的顺序使下面这个表达式(名字设为 F ( a ) F(a) )的值最大,输出这个新的ar序列 f ( f ( f ( . . . f ( a [ 1 ] , a [ 2 ] ) , a 3 ) ,   a [ n 1 ) , a [ n ] ) f(f(f(...f(a[1],a[2]),a3),~a[n-1),a[n])
  • 思路
  1. 有了上面的新的二进制运算分析,我们可以发现如果序列a中n数的某个二进制位置i,只有一个数在该这个二进制位置i上是1(我们设这个数为x),其他的都是0,那么我们只需要把x放到序列a的第一个位置上,那么x的二进制i位置上对应的1才对答案有贡献(因为此时 f ( x , y ) f(x,y) (y是除x外的任意一个数),才会出现1与0对1的情况,否则都话无论x放在a中出第一个位置外的任何一个位置x的i位置对应的数字都不可能对答案有贡献),在我们一旦选定好x的位置之后,a中其他数无论怎样的顺序都不会对答案有影响,
  2. 有了3的推理,发现要想 F ( a ) F(a) 的值最大,仅与我们选定 a [ 1 ] a[1] 的值对答案的贡献大小有关,这个时候就要确的a[1]在序列a中n数的某个二进制位置i,只有一个数在该这个二进制位置i上是1,且这个i的位置一定越大越好(对答案的贡献大)
  3. 剩下就是,枚举找到符合题意的a[1]了直接看代码更容易。。

代码

#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <deque>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
#define ios ios::sync_with_stdio(false); 
#define endl '\n'
#define PI acos(-1)
#define PB push_back
#define ll long long
#define db double
#define INF 0x3f3f3f3f
#define mod 998244353
#define lowbit(abcd) (abcd & (-abcd))

const int mxn = 2e5 + 10;
int n;
int ar[mxn];

int main()
{
    /* fre(); */
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++)
        scanf("%d", &ar[i]);
    sort(ar + 1, ar + 1 + n, greater<int>());

    int fg = 0;
    int pos;
    for(int i = 30; i >= 0; i --)
    {
        fg = 0;
        for(int j = 1; j <= n; j ++)
        {
            if((1 << i) & ar[j])
            {
                fg ++;
                if(fg == 1)
                    pos = j;
                else
                    break;
            }
        }
        if(fg == 1) break;
    }

    if(fg == 1)
    {
        printf("%d ", ar[pos]);
        for(int i = 1; i <= n; i ++)
        {
            if(i != pos)
            {
                printf("%d ", ar[i]);
            }
        }
    }
    else	//如果出现a中n个数所有相应的二进制位出现次数超过2次
    {
        for(int i = 1; i <= n; i ++)
            printf("%d ", ar[i]);
    }

    return 0;
}


D. Aerodynamic(几何,思维)

分析

在这里插入图片描述
代码不难理解,就是题意难理解。。。

代码

#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <deque>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
#define ios ios::sync_with_stdio(false); 
#define endl '\n'
#define PI acos(-1)
#define PB push_back
#define ll long long
#define db double
#define INF 0x3f3f3f3f
#define mod 998244353
#define lowbit(abcd) (abcd & (-abcd))

const int mxn = 2e5 + 10;
int a[mxn], b[mxn];
int n;
db f[mxn];
int len[mxn];

int main()
{
    /* fre(); */
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++)
        scanf("%d %d", &a[i], &b[i]);

    if(n % 2)
        printf("nO\n");
    else
    {
        int fg = 1;
        for(int i = 1; i <= n/2; i ++)
        {
            if(a[i] + a[i + n/2] != a[1] + a[1 + n/2] || b[i] + b[i + n/2] != b[1] + b[1 + n/2])
            {
                fg = 0;
                break;
            }
        }
        if(fg)
            printf("YES\n");
        else
            printf("nO\n");
    }


    return 0;
}


E. Water Balance(贪心)

分析

  • 题意
  1. 给我有n个数的序列a,每次操作我们可以选择一个区间 [ l , r ] [l,r] ,将这个区间内的元素用这个区间内的平均数来代替,问通过这样一些操作之后我们能得到的a的字典序最小是多少?
  • 思路
  1. 我们设两端相邻的之前操作计算过平均数的区间, s 1 , s 2 s1,s2 ,对于的平均数为 f 1 , f 2 f1,f2 ,我们在假设区间 s 2 s2 区间挨着的下一个位置为i,我们可以把i位置作为一个单独的平均数区间 s 3 s3 ,对应的 s 3 s3 区间平均数为 f 3 f3 ,如果 f 3 < f 2 f3<f2 我们把s3区间拼接到s2区间上,形成新的s2区间能得到更小的新平均数 f 2 f2 ,从而得到更小的字典序,,,如果 f 2 < f 1 f2<f1 ,我继续进行区间合并操作,得到更小的区间平均值,,,这样一直向前循环合并区间下去,就能得到答案

代码

#include <iostream>
#include <algorithm>
#include <map>
#include <set>
#include <list>
#include <queue>
#include <deque>
#include <cmath>
#include <stack>
#include <vector>
#include <cstdio>
#include <string>
#include <cstring>
using namespace std;
void fre() { freopen("A.txt", "r", stdin); freopen("Ans.txt","w",stdout); }
#define ios ios::sync_with_stdio(false); 
#define endl '\n'
#define PI acos(-1)
#define PB push_back
#define ll long long
#define db double
#define INF 0x3f3f3f3f
#define mod 998244353
#define lowbit(abcd) (abcd & (-abcd))

const int mxn = 2e6 + 10;
int ar[mxn];
int n;
db f[mxn];
int len[mxn];

int main()
{
    /* fre(); */
    scanf("%d", &n);
    for(int i = 1; i <= n; i ++)
        scanf("%d", &ar[i]);
    int p = 0;
    for(int i = 1; i <= n; i ++)
    {
        f[++ p] = ar[i]; len[p] = 1;            //f[p] 表示第p段的平均数,len[p] 表示第p段段长度
        while(p > 1 && f[p] < f[p - 1])
        {
            f[p - 1] = (f[p - 1] * len[p - 1] + f[p] * len[p]) / (len[p - 1] + len[p]);
            len[p - 1] += len[p];
            p --;
        }
    }

    for(int i = 1; i <= p; i ++)
    {
        for(int j = 0; j < len[i]; j ++)
            printf("%.9f\n", f[i]);
    }

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_34261446/article/details/106292675
今日推荐