当前位置: 代码迷 >> 综合 >> codeforces 1038B Non-Coprime Partition
  详细解决方案

codeforces 1038B Non-Coprime Partition

热度:31   发布时间:2023-11-19 23:34:36.0

题目链接:http://codeforces.com/problemset/problem/1038/B
题目意思:题目会输入一个n,然后要求你将1至n 总共n个数分成两部分,每部分组成一个集合,记为A1,A2。然后对每个集合中的所有元素求和记为S1和S2。要求S1和S2不能互质。如果存在这两个集合,则按照题意输出(在这里提醒一下Yes和No的输出,一定要按照题目的Yes和No输出)。
题解思路:
易错思路:“这道题一看,很容易进入循环,因为我们已经知道n个数之和是n(n+1)/2,那么我们只要循环一次,找到一个k使得k和(n(n+1)/2-k)不互质就行。这种想法是可以的,但是很难实现,因为你要找k还要判断是否互质,并且你还要找到之和为k的集合并且要输出。这样做应该会超时(我没有试过,读者可以自己尝试一下)。”
其实我们仔细看看样例2就可以看出他是分奇偶输出(不排除是样例的偶然性,但是我们可以去想想奇偶是否可行,因此这就是一道数学题了)
分析如下:
假如n是偶数。
所有偶数是2、4、6、、、、n 总和是((n+2)n/2)/2也就是n(n+2)/4=(n/2)(n/2+1)
那么奇数之和就是n*n/4=(n/2)*(n/2)
所以可以清楚的知道至少有一个公因数n/2。
n是奇数的情况读者可以自己考虑,他们会有一个公因数(n+1)/2
从以上可以发现:
1)当n=1、2时是互质的。输出No就完事
2)当n>2时,必定会有公因数。只要分奇偶输出就可以。

#include <bits/stdc++.h>
using namespace std;int main()
{int n;scanf("%d",&n);if(n<3){
   cout<<"No";exit(0);}cout<<"Yes"<<endl;if(n%2){cout<<(n+1)/2;for(int i=1;i<=n;i+=2)cout<<" "<<i;cout<<endl;cout<<(n-1)/2;for(int i=2;i<=n;i+=2)cout<<" "<<i;}else {cout<<n/2;for(int i=1;i<=n;i+=2)cout<<" "<<i;cout<<endl;cout<<n/2;for(int i=2;i<=n;i+=2)cout<<" "<<i;}return 0;
  相关解决方案