分区号从1到n

时间:2018-01-10 17:01:14

标签: c++ numbers partition

挑战是

  

给定两个整数x和N.考虑1之间的所有整数   除了x之外,还包括N和。我们想将这些整数划分为   两个不相交的集合(每个整数必须恰好出现在一个集合中)   这些集合中的数字总和是相等的。找一个有效的   分区或确定它不存在。

这是在codechef的编码竞赛中提出来的,我在 C ++ 中为它编写了一个解决方案,但这说错了答案。

这是我的代码

`#include<bits/stdc++.h>
using namespace std;
main(){
    int t;
    cin>>t;
    while(t--){
        int n,x;
        cin>>x>>n;
        long long int sum = (n*(n+1))/2;
        sum = sum - x;
        if( ( (sum%2)==1 ) || n==2){
            cout<<"impossible";
        }
        else{
            sum /= 2;
            stack<char> s;
            for(int i=n;i>=1;i--){
                if(i!=x){
                    if( (sum-i) >= 0){
                        s.push('0');
                        sum = sum - i;
                    }else
                        s.push('1');
                }else
                    s.push('2');
            }
            if(s.top()=='0'){
                while(!s.empty()){
                    cout<<s.top();
                    s.pop();
                }
            }else if(s.top()=='1'){
                while(!s.empty()){
                    if(s.top()=='1')
                        s.top() = '0';
                    else if(s.top()=='0')
                        s.top() = '1';
                    cout<<s.top();
                    s.pop();
                }
            }else{
                cout<<s.top();
                s.pop();
                if(s.top()=='0'){
                    while(!s.empty()){
                        cout<<s.top();
                        s.pop();
                    }
                }else{
                    while(!s.empty()){
                        if(s.top()=='1')
                            s.top() = '0';
                        else if(s.top()=='0')
                            s.top() = '1';
                        cout<<s.top();
                        s.pop();
                    }
                }
            }
        }
        cout<<endl;
    }
    return 0;
}`

我在这里做的是我首先找到从1到N的所有数字的总和,然后从中删除x,之后如果总和是奇数,那么你就不能将数字分成2个不相交的集合所以打印&#34;不可能&#34;,如果它不是奇数,那么你将它减半,每一组将总和达到这个并开始从N到1的循环并开始从总和中减去i,只要sum-i是&gt; = 0.

对于每个减法,你把它放在一个堆栈中作为&#39; 0&#39;和&#39; 1&#39;以便区分这两个群体。当我变得等于x时,你插入一个&#39; 2&#39;。

最后打印堆栈。在这里打印堆栈可能看起来很复杂,因为首先当我尝试打印它时,结果显示错误的答案,所以我认为它取了i = 1的组作为组&#39; 0&#39;和其他人作为小组&#39; 1&#39;。

答案仍未到来。请任何人告诉我在任何地方是否有错,我不是要求直接代码或答案只是想知道我做错了什么。任何帮助,将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:0)

您的算法不适用于所有情况。这是一个反例 取N = 8x = 2; set to partition为S = {1, 3, 4, 5, 6, 7, 8},每个分区的总和为17 解决方案是A = {1, 3, 5, 8}, B = {4, 6, 7} 以下是您的算法将尝试解决的问题:

A = {}, B = {}, sum = 17
A = {8}, B = {} sum = 9
A = {8, 7}, B = {} sum = 2
A = {8, 7}, B = {6} sum = 2
...
A = {8, 7}, B = {6, 5, 4, 3} sum = 2
A = {8, 7, 1}, B = {6, 5, 4, 3} sum = 1

正如您所看到的,因为S不包含2,所以您的算法没有提出sum = 0的解决方案。 只需添加条件(sum-i) != x即可使算法正常工作。显然,这也不起作用。

这是一个更复杂的解决方案。首先让我们做一些观察。

根据N % 4x必须为奇数或偶数才能存在解。实际上,如果N % 4 = 0N % 4 = 3,则N*(N+1)/2为偶数,否则为奇数。此外,x必须具有相同的奇偶校验,因为N*(N+1)/2 - x必须是偶数。

此外,任何4个连续整数的集合都可以用相等的和分割成两组:一组中的第一个和最后一个整数,另一组中的两个中间整数。

我们来看N = 4。如果x = 2,则解决方案为A = {1, 3}, B = {4}。如果x = 4,则解决方案为A = {1, 2}, B = {3}

将上一个示例与N = 8x = 2结合使用,我们可以删除{5, 6, 7, 8},将问题减少到前一个N = 4x = 2。这给了A = {5, 8, 1, 3}, B = {6, 7, 4}

我们可以为N % 4 = 0定义两个基本案例,通过从x-1降序和N中移除4个连续整数的序列,可以将任何其他案例简化为基本案例降。基本案例为S = {1, x+1, x+2}S = {1, 2, 3}

使用相同的流程,我们可以为N % 4 = 1定义基本案例:基本案例为S = {}S = {1, 2, x+1, x+2}

对于N % 4 = 2,过程略有不同:要删除的序列来自2升序和N降序。基本案例为S = {2, 3, 4, 5, 6}S = {1, x-1, x+1, x+2, x+3}S = {1, x-3, x-2, x-1, x+1}。例如,对于N = 14x = 7,删除{2, 3, 4, 5}{11, 12, 13, 14}会留下S = {1, 6, 8, 9, 10},这对应于第二个基本情况。

对于N % 4 = 3,流程略有不同:要删除的序列来自1升序,N降序。基本案例为S = {x-1, x+1, x+2, x+3, x+4, x+5}S = {x-3, x-2, x-1, x+1, x+2, x+3}S = {x-5, x-4, x-3, x-2, x-1, x+1}

以下是快速摘要。

N % 4 = 0
x-1降序和N降序删除序列,直至下列其中一项 S = {1, x+1, x+2}; A = {1, x+1}, B = {x+2}
S = {1, 2, 3}; A = {1, 2}, B = {3}

N % 4 = 1
x-1降序和N降序删除序列,直至下列其中一项 S = {}; A = {}, B = {}
S = {1, 2, x+1, x+2}; A = {1, x+2}, B = {2, x+1}

N % 4 = 2
2升序和N降序删除序列,直到下列之一 S = {2, 3, 4, 5, 6}; A = {2, 3, 5}, B = {4, 6}
S = {1, x-1, x+1, x+2, x+3}; A = {1, x-1, x+3}, B = {x+1, x+2}
S = {1, x-3, x-2, x-1, x+1}; A = {1, x-2, x-1}, B = {x-3, x+1}

N % 4 = 3
1升序和N降序删除序列,直到下列之一 S = {x-1, x+1, x+2, x+3, x+4, x+5}; A = {x-1, x+3, x+5}, B = {x+1, x+2, x+4}
S = {x-3, x-2, x-1, x+1, x+2, x+3}; A = {x-3, x+1, x+2}, B = {x-2, x-1, x+3}
S = {x-5, x-4, x-3, x-2, x-1, x+1}; A = {x-5, x-3, x+1}, B = {x-4, x-2, x-1}