Codeforces Round #618 (Div. 2)

QAQ我太难了

A. Even But Not Even

题意:

给你一个长度为n的数组a,你可把其中一个数的值加一,这个操作你可以做无数次,要求最后的数组之和不等于零,数组之积不等于0,输出所需最小的操作数。

思路:

暴力模拟即可,要求数组中不能有0,和不等于0

代码:

#include <bits/stdc++.h>
using namespace std;
int num[105];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int n;
        cin >> n;
        int sum = 0,ans = 0;
        for(int i = 0;i<n;++i)
        {
            cin >> num[i];
            if(num[i]==0)
            {
                ans++;
                sum+=1;
            }
            else
            {
                sum+=num[i];
            }
        }
        if(sum!=0)
            printf("%d\n",ans);
        else
            printf("%d\n",ans+1);
    }
    return 0;
}

B. Array Sharpening

题意:

给你一个数组n,n保证是个偶数,将这两个数组划分为等大小的两个数组,使这两个数组中位数之差的绝对值最小。输出这个最小值。

思路:

将数组从小到大排序,答案就是位于中间的两个数差的绝对值。

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
typedef long long LL;
LL num[maxn];
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
       int n;
       cin >> n;
       n*=2;
       LL sum1 = 0,sum2 = 0;
       for(int i = 0;i<n;++i)
        cin >>num[i];
       sort(num,num+n);
       cout << abs(num[n/2]-num[n/2-1]) << endl;
    }
    return 0;
}

C. Anu Has a Function

题意:

定义一个函数F(x,y) = (x|y)-y,给你一个函数,你可以将其重新排列,使得F(F……F(F(a1, a2),a3……an-1),an)的值最大,输出重新排序后的数组。

思路:

首先,我们来分析下二进制下的这个函数,可以发现这个函数的结果就是先把所有xy都是1的位变成0之后得到的数,这表示对于所有数的某一位来说,只要这一位的1的个数大于1,那么最终结果上这一位就会变成0,因此,我们需要遍历数组统计每一位是1的数的个数,然后从高位到低位遍历,找到第一个只出现1次的那一位,将提供这一位的那个数作为第一个数,剩下的数的顺序不会影响到最终结果,按照顺序输出就好。

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+10;
typedef long long LL;
LL num[maxn];
vector<LL>vec;
int d[35],mp[35];
int main()
{

  int n;
  scanf("%d",&n);
  for(int i = 1;i<=n;++i)
  {
      scanf("%lld",&num[i]);
      for(LL j = 0;j<=31;++j)
      {
          if(LL(1<<j)&num[i])
          {
              //cout << (1<<j) <<endl;
              d[j]++;
              mp[j] = i;
          }
      }
  }
  int k= -1;
  for(int i = 31;i>=0;--i)
    {
        if(d[i]==1)
        {
            k = mp[i];
            break;
        }
    }
    if(k!=-1)
    {
        cout << num[k];
    for(int i = 1;i<=n;++i)
    {
        if(i==k)
            continue;
        cout << " " << num[i];
    }
    cout << "\n";
    }
    else
    {
        cout <<num[1];
        for(int i = 2;i<=n;++i)
        {
            cout << " " <<num[i];
        }
        cout << "\n";
    }

    
    return 0;
}

D. Aerodynamic

题意:

给你n个点,这n个点能够成一个凸包P

思路:

题目有点复杂,但是最后的结论是判断P是不是一个中心对称图形。解析可以看这个https://www.bilibili.com/video/av87962198?p=4

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5+10;
typedef long long LL;
pair<LL,LL>p[maxn];
set<pair<LL,LL> > s;
int main()
{
    int n;
    scanf("%d",&n);
    LL x=0,y=0;
    for(int i = 0;i<n;++i)
    {
        cin >>p[i].first >> p[i].second;
        x+=p[i].first;
        y+=p[i].second;
        s.insert(p[i]);
    }

    //cout <<x << " " << y <<endl;
  //  p[n].first = x,p[n].second= y;
    bool flag = true;
    for(auto it = s.begin();it!=s.end();++it)
    {
        LL x1 = (2*x-n*(it->first))/n;
        LL y1 = (2*y-n*(it->second))/n;
        //cout <<it->first << " " << it->second << " " << x1 << " " << y1 << endl;
        if(s.find(make_pair(x1,y1))==s.end())
        {
            flag = false;
            break;
        }
    }
    if(flag)
        printf("YES\n");
    else
        printf("NO\n");
    return 0;
}

E. Water Balance

题意:

给你一个数组,你可以选择一个区间,并把这个区间里的所有数替换成为这个区间的平均数,求所能得到的字典序最小的数组。

思路:

我们可以先把每一个数都当做是一个区间,用平均数去替代区间的操作可以看作是两个相邻区间的合并,因此,我们可以从左到右遍历数组,对于每一个区间,如果它的平均值比上一个区间的平均值要小,则将这两个区间合并就一定可以降低上一个区间的平均值,对于新得到的区间,也进行同样的操作,知道不能向前合并为止。得到的就是最终的结果。还有就是要注意一下输入优化。细节可以见代码。

代码:

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;
int n,p;
double a[maxn],len[maxn],st[maxn];
int main()
{
    cin >> n;
    for(int i = 1;i<=n;++i)
    {
        int x;
        cin >> x;
        a[i] = 1.0*x;
    }
    for(int i = 1;i<=n;++i)
    {
        st[++p] = a[i];
        len[p] =1;
        while(p>1&&st[p]<st[p-1])
        {
            st[p-1] = (st[p]*len[p]+st[p-1]*len[p-1])/(len[p]+len[p-1]);
            len[p-1]+=len[p];
            --p;
        }
    }
    for(int i = 1;i<=p;++i)
    {
        for(int j = 1;j<=len[i];++j)
            cout << setprecision(12) << st[i]  << "\n";
    }

    return 0;
}

 

posted @ 2020-03-09 00:40  浅花迷人  阅读(178)  评论(0编辑  收藏  举报