Codeforces Round #825 (Div. 2)

A. Make A Equal to B
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
You are given two arrays a and b of n elements, each element is either 0 or 1.

You can make operations of 2 kinds.

Pick an index i and change ai to 1−ai.
Rearrange the array a however you want.
Find the minimum number of operations required to make a equal to b.

Input
Each test contains multiple test cases. The first line contains a single integer t (1≤t≤400) — the number of test cases. Description of the test cases follows.

The first line of each test case contains a single integer n (1≤n≤100) — the length of the arrays a and b.

The second line of each test case contains n space-separated integers a1,a2,…,an (ai is 0 or 1), representing the array a.

The third line of each test case contains n space-separated integers b1,b2,…,bn (bi is 0 or 1), representing the array b.

Output
For each test case, print the minimum number of operations required to make a equal to b.

Example
inputCopy
5
3
1 0 1
0 0 1
4
1 1 0 0
0 1 1 1
2
1 1
1 1
4
1 0 0 1
0 1 1 0
1
0
1
outputCopy
1
2
0
1
1
Note
In the first case, we need only one operation: change a1 to 1−ai. Now a=[0,0] which is equal to b.

In the second case, the optimal way is to rearrange a to get the array [0,1,11. Now a=[0,0,1] which is equal to b.

In the second case, one of optimal ways would be to first change a3 to 1−a3, then rearrange a.

In the third case, no operation is needed.

In the fourth case, the optimal way is to rearrange a to get the array [0,1,1,0].

题意就是有两个操作将a的0变成1,1变成0还有一个操作就是将a数组重新排序,如何求最小操作次数

这里用vector 存a数组和b数组这样可以直接比较两个数组是否相同,然后统计a数组和b数组中各自的总和 如果一开始a数组和b数组相同就输出0,如果a数组的总和 和b数组的总和相同的话就输出1

如果都不相同的话就找如果出现a和b都不同,并且a都出现0和1,也就是a为0的时候b是1,a是1的时候b是0,这样同时出现的话就重新排序这样是最优,剩下的就是让将两个总和相减取绝对值就是答案

#include<bits/stdc++.h>
using namespace std;
const int N=1100;
 
 
int n;
 
int main()
{
    int T;
    cin>>T;
    while(T--)
    {
        vector<int>a,b;
        cin>>n;
        int sa=0;
        for(int i=0;i<n;i++)
        {
            int x;
            cin>>x;
            a.push_back(x);
            sa+=x;
        }
        int sb=0;
        for(int i=0;i<n;i++)
        {
            int x;
            cin>>x;
            b.push_back(x);
            sb+=x;
        }
       
       if(a==b)puts("0");
      else if(sa==sb)puts("1");
       else
       {
        bool cnt1=0,cnt0=0;
        for(int i=0;i<n;i++)
        {
           if(a[i]!=b[i])
           {
               if(a[i]==1)cnt1=1;
               if(a[i]==0)cnt0=1;
           }
        }
        int res=0;
        if(cnt0&&cnt1)res++;   
        res+=abs(sa-sb);
        printf("%d\n",res);
       }
        
    }
    return 0;
}

B. Playing with GCD

You are given an integer array a of length n.

Does there exist an array b consisting of n+1 positive integers such that ai=gcd(bi,bi+1) for all i (1≤i≤n)?

Note that gcd(x,y) denotes the greatest common divisor (GCD) of integers x and y.

Input
Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤105). Description of the test cases follows.

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

The second line of each test case contains n space-separated integers a1,a2,…,an representing the array a (1≤ai≤104).

It is guaranteed that the sum of n over all test cases does not exceed 105.

Output
For each test case, output "YES" if such b exists, otherwise output "NO". You can print each letter in any case (upper or lower).

题意是:判断是否能构造一个b数组,其中b数组的元素个数为n+1个,使得gcd(b+1,bi)=ai

思路就要找出ai的最小的公倍数,如果最小的公倍数都满足a数组那肯定就满足

a[i]=gcd(b[i+1],b[i])那么能够推出a[i-1]=gcd(b[i],b[i-1),可以得到b[i]肯定是a[i],a[i-1]的公倍数

所以在满足最低限度的情况下也就是b[i]是a[i-1]和a[i]的最小公倍数构造b[i]

b[i]=lcm(a[i],a[i-1])

代码:

#include<bits/stdc++.h>
using namespace std;
const int N=110000;

int n;
int a[N];
int b[N];

int gcd(int a,int b)
{
	 return b>0 ? gcd(b,a%b):a;
}

int lcm(int a,int b){
		return a/gcd(a,b)*b;
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
          scanf("%d",&a[i]);
          
         b[1]=a[1];
         b[n+1]=a[n];
         for(int i=2;i<=n;i++)
           b[i]=lcm(a[i-1],a[i]);
         
         bool flag=true;
         for(int i=1;i<=n;i++)
         {
             if(a[i]!=gcd(b[i],b[i+1])){flag=false;break;}
         }
         if(flag)puts("YES");
         else puts("NO");
    }
    return 0;
}

C1. Good Subarrays (Easy Version)

This is the easy version of this problem. In this version, we do not have queries. Note that we have multiple test cases in this version. You can make hacks only if both versions of the problem are solved.

An array b of length m is good if for all i the i-th element is greater than or equal to i. In other words, b is good if and only if bi≥i for all i (1≤i≤m).

You are given an array a consisting of n positive integers. Find the number of pairs of indices (l,r), where 1≤l≤r≤n, such that the array [al,al+1,…,ar] is good.

Input
Each test contains multiple test cases. The first line contains the number of test cases t (1≤t≤2⋅105). Description of the test cases follows.

The first line of each test case contains an integer n (1≤n≤2⋅105), the length of the array a.

The second line of each test case contains n space-separated integers a1,a2,…,an (1≤ai≤n), representing the array a.

It is guaranteed that the sum of n over all test cases does not exceed 2⋅105.

Output
For each test case, print the number of suitable pairs of indices.

Example
inputCopy
3
3
1 2 3
3
1 1 1
4
2 1 4 3
outputCopy
6
3
7
Note
In the first test case, all subarrays of a are good, so all pairs are suitable.

In the second test case, the pairs (1,1), (2,2), and (3,3) are suitable. For example, when (l,r)=(1,2), the array b=[1,1] is not good because b2<2.

这题的意思是 有多少个区间满足b[i]>=i是,每个区间的左端点都是从1开始

双指针即可 枚举区间长度记得要开longlong

#include<bits/stdc++.h>
using namespace std;
const int N=210000;
typedef long long ll;
int a[N];
int n;
 
int main()
{
	int T;
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d",&n);
		for(int i=1;i<=n;i++)scanf("%d",&a[i]);
		ll res=0;
		for(int i=1,j=1;i<=n;i++)
		{
			while(j<=n&&a[j]>=j-i+1)j++;
			res+=0ll+((ll)j-i);
		}
		printf("%lld\n",res);
	}
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值