部分和问题

时间限制:1000 ms  |  内存限制:65535 KB
难度:2
 
描述
给定整数a1、a2、.......an,判断是否可以从中选出若干数,使它们的和恰好为K。
 
输入
首先,n和k,n表示数的个数,k表示数的和。
接着一行n个数。
(1<=n<=20,保证不超int范围)
输出
如果和恰好可以为k,输出“YES”,并按输入顺序依次输出是由哪几个数的和组成,否则“NO”
样例输入
4 13 1 2 4 7
样例输出
YES 2 4 7
来源
经典题目
上传者

TC_杨闯亮

不去重也能过。 。 。开始没看到情况不符输出“NO”, WA了两次。

#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
int Have[22], dis[20], vis[22]; int n, T, ans;
void Dfs(int a, int b, int c)
{
    if(b == T)
    {
        if(!ans)
            printf("YES\n");
        for(int i = 0; i < c; i++)
            printf(i==0?"%d":" %d", dis[i]);
        printf("\n");
        ans++;
    }
    for(int i = a; i < n; i++)
    {
        if(vis[i])
            continue;
        vis[i] = 1;
        dis[c] = Have[i];
        Dfs(i+1, b + Have[i], c + 1);
        vis[i] = 0;     
        while(i + 1 < n && Have[i] == Have[i+1])    //去重;  
            i++;    
    }
}
int main()
{
    while(~scanf("%d %d", &n, &T))
    {
        ans = 0;
        memset(vis, 0sizeof(vis));
        for(int i = 0; i < n; i++)
            scanf("%d", &Have[i]);
        Dfs(000);
        if(!ans)
            printf("NO\n");
    }
    return 0;    

 

两份代码, 你找到不同了吗? 

#include <cstdio>
#include <cstring>
const int N = 21;
int n, k;
int dis[N], vis[N], num[N];
int cnt;
void Dfs(int A, int sum, int a){
    if(sum == k){
        if(!cnt){
            printf("YES ");
            for(int i = 0; i < a; i++)
                printf(i == a-1? "%d\n":"%d ", dis[i]);
        }
        cnt++;
    } 
    for(int i = 0; i < n; i++){
        if(vis[i])
            continue;
        vis[i] = 1;
        dis[a] = num[i];
        Dfs(i+1, sum+num[i], a+1);
        vis[i] = 0;
    }
    
}
int main(){
    scanf("%d%d", &n, &k);
    cnt = 0;
    memset(vis, 0, sizeof(vis));
    for(int i = 0; i < n; i++)
        scanf("%d", &num[i]);
    Dfs(0, 0, 0);
    if(!cnt)
        printf("NO\n"); 
    return 0;
} 

 

posted on 2015-09-02 13:59  cleverbiger  阅读(186)  评论(0编辑  收藏  举报