• Codeforces Round #717 (Div. 2) A


    OB局,最近莽数据库作业没什么时间,大晚上也挺困的。

    A - Tit for Tat

    概括来讲,对于(n)个数,最多进行(k)次操作,每次操作可以使一个数-1,一个数+1,最终得到的序列字典序最小。

    每次操作就对第一个非0的数-1,对最后一个数+1。

    如果第一个非0的数就是最后一个数,就可以停止操作了。

    /* Author: EndlessK
     * Time: 2021-04-22 12:37:38
    **/
    #include<bits/stdc++.h>
    #define maxn 100010
    #define pb push_back
    #define ll long long
    #define fast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    using namespace std;
    int a[110];
    int main()
    {
        fast;
        int t;
        cin>>t;
        while(t--)
        {
            int n,k;
            cin>>n>>k;
            for(int i=1;i<=n;i++)
            {
                cin>>a[i];
            }
            int temp=1;
            for(int i=1;i<=k;i++)
            {
                while(a[temp]==0 && temp<n) temp++;
                if(temp==n) break;
                a[temp]--;
                a[n]++;
            }
            for(int i=1;i<=n;i++)
            {
                cout<<a[i]<<' ';
            }
            cout<<'
    ';
        }
        return 0;
    }
    View Code

    B - AGAGA XOOORRR

    当时口糊一个算法,随便写了一发让别人交了,A了,第二天起来自己交Wrong answer on test 18,效果拉满。

    题目概括起来讲就是将一个序列分成若干段,使得这几段的异或和相等。

    两个相等的数异或和为0。

    先求序列所有数字的异或和,如果为0,那么整个序列必然可以分成两段使得这两段的异或和相等。

    如果不为0,那么留下的这个数字就是每段异或和的值(sum)。那么我就看前面异或和为0的部分能不能分成两段异或和为(sum)的序列。

    当晚口糊的居然是看每一小段异或和为0的部分能不能分成两段异或和为(sum)的序列。早晨起来发现加了17和18两组,正好叉掉了。

     1 #include <bits/stdc++.h>
     2 #define maxn 100010
     3 #define pb push_back
     4 #define ll long long
     5 #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
     6 const ll mod = 1e9 + 7;
     7 using namespace std;
     8 int n;
     9 int a[2020];
    10 int sum[2020] = {0};
    11 vector<int> v;
    12 bool check(int l, int r)
    13 {
    14     int temp = 0;
    15     for (int i = l; i <= r; i++)
    16     {
    17         temp = temp ^ a[i];
    18         if (temp == sum[n])
    19             return 1;
    20     }
    21     return 0;
    22 }
    23 int main()
    24 {
    25     int t;
    26     cin >> t;
    27     while (t--)
    28     {
    29         v.clear();
    30         cin >> n;
    31         for (int i = 1; i <= n; i++)
    32         {
    33             cin >> a[i];
    34             sum[i] = sum[i - 1] ^ a[i];
    35             if (sum[i] == 0)
    36                 v.pb(i);
    37         }
    38         if (sum[n] == 0)
    39             cout << "YES
    ";
    40         else
    41         {
    42             if (v.size() == 0)
    43             {
    44                 cout << "NO
    ";
    45                 continue;
    46             }
    47             int flag = 1;
    48             int tmp = 1;
    49             if(check(1,v[v.size()-1])) cout<<"YES
    ";
    50             else cout<<"NO
    ";
    51         }
    52     }
    53 }
    View Code

    C - Baby Ehab Partitions Again

    隔壁的暴力居然过了,虽然我到现在还在怀疑是不是对的。

    概括起来就是,判断能不能将所有数字分成两组使得两组和相等,不能则为0,若能,问最少删除多少个数字使得无法分成符合条件的两组。

    1.和为奇数,结果必为0。

    2.和为偶数,若数字中有奇数,删除奇数。

    3.对于上一条,若全为偶数,则不断除2,直至奇数出现,而那个奇数就是我们需要删除的数字。

    对于所有可能和的求解像极了蓝桥的砝码称重()

    终于想到用背包写了,谢天谢地,不然我还在那写set。

    /* Author: EndlessK
     * Time: 2021-04-22 12:37:38
    **/
    #include<bits/stdc++.h>
    #define maxn 100010
    #define pb push_back
    #define ll long long
    #define fast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    using namespace std;
    int a[120];
    int sum=0;
    int main()
    {
        fast;
        int n;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
            cin>>a[i];
            sum+=a[i];
        }
        if(sum%2)
        {
            cout<<"0
    ";
            return 0;
        }
        ll dp[sum/2+1][n+1];
        memset(dp,0,sizeof(dp));
        for(int i=0;i<=n;i++)
        {
            dp[0][i]=1;
        }
        for(int i=1;i<=sum/2;i++)
        {
            for(int j=1;j<=n;j++)
            {
                dp[i][j]=dp[i][j-1];
                if(i>=a[j-1])
                dp[i][j]=max(dp[i-a[j-1]][j-1],dp[i][j]);
            }
        }
        if(dp[sum/2][n]==0)
        {
            cout<<"0
    ";
            return 0;
        }
        for(int i=1;i<=16;i++)
        {
            for(int j=1;j<=n;j++)
            {
                if(a[j]%2)
                {
                    cout<<"1
    "<<j<<'
    ';
                    return 0;
                }
                else a[j]/=2;
            }
        }
        return 0;
    }
    View Code

    之后有空补一下剩下两道题。

  • 相关阅读:
    8位单片机可用的 mktime localtime函数
    【转载】linux获取mac地址
    【转载】openwrt框架分析
    JVM调优工具Arthas的使用
    Grafana监控JVM
    JAVA死锁排查-性能测试问题排查思路
    JVM的堆内存泄漏排查-性能测试
    性能测试之JVM的故障分析工具VisualVM
    性能测试之 JVM 异常说明和分析工具
    性能测试之 JVM 概念认识
  • 原文地址:https://www.cnblogs.com/endlesskkk/p/14689771.html
Copyright © 2020-2023  润新知