Codeforces Round #829 (Div. 2)

C1. Make Nonzero Sum (easy version)

题目:

You are given an array [a1,a2,…an] consisting of integers −1 and 1. You have to build a partition of this array into the set of segments [l1,r1],[l2,r2],…,[lk,rk]

with the following property:

  • Denote the alternating sum of all elements of the i

-th segment as si: si = ali−ali+1+ali+2−ali+3+…±ari. For example, the alternating sum of elements of segment [2,4] in array [1,0,−1,1,1] equals to 0−(−1)+1=2

  • .
  • The sum of si
  • over all segments of partition should be equal to zero.

Note that each si

does not have to be equal to zero, this property is about sum of si

over all segments of partition.

The set of segments [l1,r1],[l2,r2],…,[lk,rk]

is called a partition of the array a of length n if 1=l1≤r1,l2≤r2,…,lk≤rk=n and ri+1=li+1 for all i=1,2,…k−1

. In other words, each element of the array must belong to exactly one segment.

You have to build a partition of the given array with properties described above or determine that such partition does not exist.

Note that it is not required to minimize the number of segments in the partition.

就逐个向后讨论。肉眼可见奇数个时不行。偶数个时,前后相等就放入一组,相消;不相等就两组分别一组,相消。

#include<bits/stdc++.h>
using namespace std;
#define IOS {cin.tie(0); cout.tie(0); ios::sync_with_stdio(0);}
using namespace std; 
typedef long long ll;
const ll p=1e9+7,N=1e7+7;
int a[N];
int main()
{
	IOS;
	int t;
	cin>>t;
	while(t--){
		int n;
		cin>>n;
		for(int i=1;i<=n;i++){
			cin>>a[i];
			//sum+=a[i];
		}
		if(n%2) cout<<"-1"<<endl;
		else{
			queue<pair<int,int>> q;
			for(int i=1;i<n;i+=2){
				if(a[i]==a[i+1]){
					q.emplace(i,i+1);
					//i++;
				} 
				else{
					q.emplace(i,i);
					q.emplace(i+1,i+1);
				} 
			}
			//if(a[n-1]!=a[n]) q.emplace(n,n);
			int t=q.size();
			cout<<t<<endl;
			while(!q.empty()){
				auto [x,y]=q.front();q.pop();
				cout<<x<<" "<<y<<endl;
			}
		}
	}
	return 0;
}

D. Factorial Divisibility

直接阶乘肯定是不行的。

但可以发现 n+1 个 n! 可以组成 (n+1)!,于是我们用数组存储每个阶乘的数量。

然后从一遍历,如果a[i]%(i+1)不等于0,那么说明该组不能构成x!,每次循环后加上a[i]/(i+1),相当于是进位。若a[n]=n+1,则显然a[n+1]会+1;

#include<bits/stdc++.h>
using namespace std;
#define IOS {cin.tie(0); cout.tie(0); ios::sync_with_stdio(0);}
using namespace std; 
typedef long long ll;
const ll p=1e9+7,N=1e7+7;
int a[N];
int main()
{
	IOS;
	ll n,x;
	cin>>n>>x;
	
	for(int i=1;i<=n;i++){
		ll k;
		cin>>k;
		a[k]++;
	}
	for(int i=1;i<x;i++){
		if(a[i]%(i+1)){
			cout<<"No";
			return 0;
		}
		a[i+1]+=a[i]/(i+1);
	}
	cout<<"Yes";
	
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值