CODEFORCES Same Parity Summands 解析

题目描述

You are given two positive integers n (1≤n≤109) and k (1≤k≤100). Represent the number n as the sum of k positive integers of the same parity (have the same remainder when divided by 2).

In other words, find a1,a2,…,ak such that all ai>0, n=a1+a2+…+ak and either all ai are even or all ai are odd at the same time.

If such a representation does not exist, then report it.

Input

The first line contains an integer t (1≤t≤1000) — the number of test cases in the input. Next, t test cases are given, one per line.

Each test case is two positive integers n (1≤n≤109) and k (1≤k≤100).

Output

For each test case print:

  • YES and the required values ai, if the answer exists (if there are several answers, print any of them);
  • NO if the answer does not exist.

The letters in the words YES and NO can be printed in any case.

思路

首先,了解这篇文章大意。这是一道构造题(据老师所说),需要将正整数n分为k个奇偶性相同的数(即都是奇数或都是偶数)。

接着来想题的做法:既然题题目跟奇偶性有关,我们就可以从变量的奇偶性入手。这里可以先讨论n的奇偶性,再在讨论k的奇偶性。

1.n为奇数

(1)k为偶数:

因为这些数的奇偶性相同,所以无论偶数个偶数,亦或偶数是个奇数,相加的结果必是偶数,所以这种情况不存在。

(2)k为奇数:

前面说过,奇数个偶数相加结果是偶数,所以我们讨论奇数个奇数相加。我们可以把每个正奇数化为1+x(x>=0&&x%2==0)而奇数减奇数等于偶数,所以我们可以将n转换为n-1*k-x,那么我们就可以把这k个数化为k-1个1和1个1+x。那我们就只需要保证x>=0,化简完之后就是需要保证k<=n,此时这k个数就可以化为k-1个1和n-k+1.

2.n为偶数

(1)k为偶数:

如前所说,无论偶数个偶数,亦或偶数个奇数,相加的结果必是偶数。所以此处既可以用奇数,也可以用偶数。但因为1<2,所以用奇数限制更小。具体代码见1(2)。

(2)k为奇数:

因为奇数个奇数相加等于奇数,所以此处不能为奇数。但偶数个奇数相加等于偶数,所以此处可以为偶数。因为是偶数,所以需要满足n>=2*k,然后可以将它转换为k-1个2和1个n-2*(k-1),证明过程如上。

代码:

以下为我的代码:

#include<bits/stdc++.h>
using namespace std;
int n,a,b,x,y;
int main(){
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>x>>y;
		if(x%2==1){
			if(y%2==0)cout<<"NO"<<endl;
			else{
				if(y>x)cout<<"NO"<<endl;
				else{
					cout<<"YES"<<endl;
					for(int j=1;j<=y-1;j++){
						cout<<1<<' ';
						x-=1;
					}
					cout<<x<<endl;
				}
			}
		}else{
			if(y%2==0){
				if(y>x)cout<<"NO"<<endl;
				else{
					cout<<"YES"<<endl;
					for(int j=1;j<=y-1;j++){
						cout<<1<<' ';
						x--;
					}
					cout<<x<<endl;
				}				
			}else{
				if(y*2>x)cout<<"NO"<<endl;
				else{
					cout<<"YES"<<endl; 
					for(int j=1;j<=y-1;j++){
						cout<<2<<' ';
						x-=2;
					}
					cout<<x<<endl;
				}
			}
		}
	}
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值