【题解】集合

题目描述

  设X是有N个不相同整数的集合。把X中每个数用两次,排成一个长度为2N的数列S,要求S中任意一个数i与另一个与它相同的i之间正好间隔i个数字。

输入输出格式

输入格式

  第一行,一个整数N(1≤N≤8)。

  第二行,有N个整数(每个数不相同,并且在0到16之间),表示集合中的数。

输出格式

  输出一个满足上面要求的长度为2N的数列;如果有多个解,输出字典序最小的解;如果没有解,输出-1。

输入输出样例

输入样例

8

8 0 12 6 2 4 3 13

输出样例

12 13 2 8 3 2 4 6 3 0 0 4 8 12 6 13

题解

  暴搜水题,相信随随便都能编出如下的程序。

#include <iostream>
#include <algorithm>

using namespace std;

int n;
int a[10];
int f[10];
int s[20];
int ans;

void DFS(int dep)
{
    if(dep > n + n)
    {
        for(register int i = 1; i < n + n; ++i)
        {
            cout << s[i] << " "; 
        }
        cout << s[n + n];
        ans = 1;
        return;
    }
    for(register int i = 1; i <= n; ++i)
    {
        if(f[i] == 1 && (dep - a[i] <= 1 || s[dep - a[i] - 1] != a[i]) || f[i] == 2) continue;
        ++f[i];
        s[dep] = a[i];
        DFS(dep + 1);
        if(ans) return;
        s[dep] = -1;
        --f[i];
    }
    return;
}

int main()
{
    cin >> n;
    for(register int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }
    sort(a + 1, a + n + 1);
    for(register int i = 1; i <= n + n; ++i)
    {
        s[i] = -1;
    }
    DFS(1);
    if(!ans) cout << -1;
    return 0;
}
参考程序

  但实际上这里有一个可以大大减小时间的剪枝要点。

  我们其实可以在更改s[dep]的时候顺便更改s[dep+a[i]+1]的值,这样到了s[dep+a[i]+1]的时候就可以直接继续向后搜了。

#include <iostream>
#include <algorithm>

using namespace std;

int n;
int a[10];
int f[10];
int s[20];
int ans;

void DFS(int dep)
{
    if(dep > n + n)
    {
        for(register int i = 1; i < n + n; ++i)
        {
            cout << s[i] << " "; 
        }
        cout << s[n + n];
        ans = 1;
        return;
    }
    if(~s[dep]) return DFS(dep + 1);
    for(register int i = 1; i <= n && dep + a[i] < n + n; ++i)
    {
        if(f[i] || ~s[dep + a[i] + 1]) continue;
        f[i] = 1;
        s[dep] = s[dep + a[i] + 1] = a[i];
        DFS(dep + 1);
        if(ans) return;
        s[dep] = s[dep + a[i] + 1] = -1;
        f[i] = 0;
    }
    return;
}

int main()
{
    cin >> n;
    for(register int i = 1; i <= n; ++i)
    {
        cin >> a[i];
    }
    sort(a + 1, a + n + 1);
    for(register int i = 1; i <= n + n; ++i)
    {
        s[i] = -1;
    }
    DFS(1);
    if(!ans) cout << -1;
    return 0;
}
参考程序(优化)

猜你喜欢

转载自www.cnblogs.com/kcn999/p/10542242.html