Codeforces Round #665 (Div. 2)

https://codeforces.com/contest/1401/problem/A

A. Distance and Axis

We have a point A with coordinate x=n on OX-axis. We’d like to find an integer point B (also on OX-axis), such that the absolute difference between the distance from O to B and the distance from A to B is equal to k.

The description of the first test case.
Since sometimes it’s impossible to find such point B, we can, in one step, increase or decrease the coordinate of A by 1. What is the minimum number of steps we should do to make such point B exist?

Input
The first line contains one integer t (1≤t≤6000) — the number of test cases.

The only line of each test case contains two integers n and k (0≤n,k≤106) — the initial position of point A and desirable absolute difference.

Output
For each test case, print the minimum number of steps to make point B exist.

Example
inputCopy
6
4 0
5 8
0 1000000
0 0
1 0
1000000 1000000
outputCopy
0
3
1000000
0
1
0
Note
In the first test case (picture above), if we set the coordinate of B as 2 then the absolute difference will be equal to |(2−0)−(4−2)|=0 and we don’t have to move A. So the answer is 0.

In the second test case, we can increase the coordinate of A by 3 and set the coordinate of B as 0 or 8. The absolute difference will be equal to |8−0|=8, so the answer is 3.

题意:在数轴正半轴上有一个A,每次操作可以增加或减少A一个单位,问最少操作几次能够使得在正半轴上取一个B使得AB和OB的差等于k

解析:首先因为A点是确定的,B点是可动的,我们可以从左到右移动B点来研究这个问题。
当B在O到A之间时,0<=k<=A 因为B必须要是整数,所以A-k如果是奇数,那么要一个操作数否则就是0
当B在A右边时,无论B取什么 k永远等于A
因此可以得出,如果0<=k<=A不需要操作,k>A时,要操作k-A次

代码:

#include<iostream>
#include<queue>
#include<string.h>
#include<stdio.h>
#define ll long long
#define inf 0x3f3f3f3f
 
using namespace std;
 
int main()
{
    int t,a,k;
    cin>>t;
    while(t--)
    {
        int ans;
        cin>>a>>k;
        if(k<a)
        {
        if((a-k)%2)
        ans=1;
        else 
        ans=0;
        }
        else 
        ans=k-a;
        printf("%d\n",ans);
    }
    getchar();
    getchar();
}

B. Ternary Sequence

You are given two sequences a1,a2,…,an and b1,b2,…,bn. Each element of both sequences is either 0, 1 or 2. The number of elements 0, 1, 2 in the sequence a is x1, y1, z1 respectively, and the number of elements 0, 1, 2 in the sequence b is x2, y2, z2 respectively.

You can rearrange the elements in both sequences a and b however you like. After that, let’s define a sequence c as follows:

ci=⎧⎩⎨aibi0−aibiif ai>biif ai=biif ai<bi
You’d like to make ∑ni=1ci (the sum of all elements of the sequence c) as large as possible. What is the maximum possible sum?

Input
The first line contains one integer t (1≤t≤104) — the number of test cases.

Each test case consists of two lines. The first line of each test case contains three integers x1, y1, z1 (0≤x1,y1,z1≤108) — the number of 0-s, 1-s and 2-s in the sequence a.

The second line of each test case also contains three integers x2, y2, z2 (0≤x2,y2,z2≤108; x1+y1+z1=x2+y2+z2>0) — the number of 0-s, 1-s and 2-s in the sequence b.

Output
For each test case, print the maximum possible sum of the sequence c.

Example
inputCopy
3
2 3 2
3 3 1
4 0 1
2 3 0
0 0 1
0 0 1
outputCopy
4
2
0
Note
In the first sample, one of the optimal solutions is:

a={2,0,1,1,0,2,1}
b={1,0,1,0,2,1,0}
c={2,0,0,0,0,2,0}
In the second sample, one of the optimal solutions is:

a={0,2,0,0,0}
b={1,1,0,1,0}
c={0,2,0,0,0}
In the third sample, the only possible solution is:

a={2}
b={2}
c={0}

题意:
给你两个长度为n的数列a,b,元素由0,1,2组成。
ai==bi 那么结果为0
ai>bi 结果为aibi
ai<bi 结果为-aibi
排列这两个数列使得这n个结果最大

分析:
发现只有a为2,b为1时才为2,a为1b为2时才为-2,其他情况全是0.因为间隔都为2,所以可以用贪心来做,2尽量多,0尽量多,剩下的才为-2,所以可以先min(z1,y2)得到2的数量,再把剩下的y1’-y2-x2得到0的数量。

代码:

#include<iostream>
#include<queue>
#include<string.h>
#include<stdio.h>
#define ll long long
#define inf 0x3f3f3f3f
 
using namespace std;
 
int main()
{
    int t,x1,y1,z1,x2,y2,z2;
    cin>>t;
    while(t--)
    {
        cin>>x1>>y1>>z1>>x2>>y2>>z2;
        int com2=min(z1,y2);
        z1-=com2,y2-=com2;
        int fu=max(0,y1-x2-y2);
        printf("%d\n",(com2-fu)*2);
    }
    getchar();
    getchar();
}

C. Mere Array

You are given an array a1,a2,…,an where all ai are integers and greater than 0.

In one operation, you can choose two different indices i and j (1≤i,j≤n). If gcd(ai,aj) is equal to the minimum element of the whole array a, you can swap ai and aj. gcd(x,y) denotes the greatest common divisor (GCD) of integers x and y.

Now you’d like to make a non-decreasing using the operation any number of times (possibly zero). Determine if you can do this.

An array a is non-decreasing if and only if a1≤a2≤…≤an.

Input
The first line contains one integer t (1≤t≤104) — the number of test cases.

The first line of each test case contains one integer n (1≤n≤105) — the length of array a.

The second line of each test case contains n positive integers a1,a2,…an (1≤ai≤109) — the array itself.

It is guaranteed that the sum of n over all test cases doesn’t exceed 105.

Output
For each test case, output “YES” if it is possible to make the array a non-decreasing using the described operation, or “NO” if it is impossible to do so.

Example
inputCopy
4
1
8
6
4 3 6 6 2 9
4
4 5 6 7
5
7 5 2 2 4
outputCopy
YES
YES
YES
NO
Note
In the first and third sample, the array is already non-decreasing.

In the second sample, we can swap a1 and a3 first, and swap a1 and a5 second to make the array non-decreasing.

In the forth sample, we cannot the array non-decreasing using the operation.

题意:
给你一个数列a,如果两个数的最大公因数等于这个数列最小的数,那么这两个数的位置可以交换,问你最终能不能得到递增的数列。
分析:
如果考察任意两个数的gcd,那么肯定会超时,我们发现只要ai时最小的数的倍数,那么ai和最小的数肯定可以交换,又发现,只要两个数都能和最小的数交换,那么这三个数肯定可以任意交换位置,我们只需要标记出可以交换的位置,sort后的数列和原数列不一样的地方一定要是可以交换的否则就不能得到目标数列。

代码:

#include<iostream>
#include<algorithm>
#include<queue>
#include<string.h>
#include<stdio.h>
#define ll long long
#define inf 0x3f3f3f3f
 
using namespace std;
 
int a[(int)1e5+5];
int b[(int)1e5+5];
int vis[(int)1e5+5];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        memset(vis,0,sizeof(vis));
        int n,minn=1e9+5;
        cin>>n;
        for(int i=1;i<=n;i++)
        {
        scanf("%d",&a[i]);
        b[i]=a[i];
        minn=min(minn,a[i]);
        }
        for(int i=1;i<=n;i++)
        {
            if(a[i]%minn==0)
            vis[i]=1;
        }
        sort(b,b+n+1);
        bool flag=true;
        for(int i=1;i<=n;i++)
        {
            if(a[i]!=b[i]&&!vis[i])
            {
            flag=false;
            break;
            }
        }
        if(flag)
        printf("YES");
        else 
        printf("NO");
        printf("\n");
 
    }
    getchar();
    getchar();
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值