Test question algorithm training number game

Problem Description
  Given a 1 ~ N permutation a [i], each time two adjacent numbers are added to get a new sequence, and then repeat this operation for the new sequence, obviously each sequence obtained is longer than the previous sequence One less, only one number left.
  For example:
  3 1 2 4
  4 3 6
  7 9
  16
  Now if we know N and the last number sum, we request the initial sequence a [i], which is an arrangement of 1 ~ N. If there are multiple answers, the one with the smallest lexicographic order is output. The data is guaranteed to be solvable.
Input format
  The first line is two positive integers n, sum
Output format
  A permutation from 1 to N
Sample input
  4 16
Sample output
  3 1 2 4
Data size and agreement
  0<n<=10
 
Idea 1: Searching with skills firstly finds the law from the data, it can be associated with Yang Hui triangle to play the table and then search
          
#include <iostream>
#include <algorithm>

using namespace std;

typedef long long LL;

const int N = 15;

int n, sum;
 int y [N] [N], a [N]; // y array Yang Hui triangle play table a array record path 
bool vis [N];

void dfs ( int cur, int s) // cur the current number s represents the total number 
{
     if (cur> n)
    {
        if (s == sum)
        {
            for (int i = 1; i <= n; i ++ ) cout << a[i] << ' ';
            exit(0);
        }
    }
    for (int i = 1; i <= n; i ++ )
    {
        if (!vis[i])
        {
            a[cur] = i;
            vis[i] = true;
            dfs (cur + 1 , s + i * y [n] [cur]); // s + current number * Yang Hui's trigonometric coefficient 
            vis [i] = false ;                   // the line is n because of careful push    
        }                                     // The example coefficients in the figure 1 3 3 1 correspond exactly to row 4 of the Yang Hui triangle 
    }                                         // that is row n 
}

int main ()
{
    cin >> n >> sum;
    
    // Yang Hui triangle playing table 
    y [ 1 ] [ 1 ] = 1 ;
     for ( int i = 1 ; i <= 13 ; i ++ )
        y[i][1] = 1, y[i][i] = 1;
    for (int i = 3; i <= 13; i ++ )
        for (int j = 1; j <= i; j ++ )
            y[i][j] = y[i - 1][j] + y[i - 1][j - 1];
    
    dfs(1, 0);
    return 0;
}

Idea 2: Completely arrange the thoughts and do it without thinking

#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
using namespace std;

typedef long long LL;

const int N = 15;

int n, sum;
int a[N];

int main ()
{
    cin >> n >> sum;
    for (int i = 1; i <= n; i ++ ) a[i] = i;
    do
    {
        int b[n][n];
        memset(b, 0, sizeof b);
        for (int i = 1; i <= n; i ++ ) b[1][i] = a[i];
        for (int i = 2; i <= n; i ++ )
            for (int j = 1; j <= n - i + 1; j ++ )
            b[i][j] = b[i - 1][j] + b[i - 1][j + 1];
        if (b[n][1] == sum)
        {
            for (int i = 1; i <= n; i ++ ) cout << a[i] << ' ';
            break;
        }
    } while (next_permutation(a + 1, a + n + 1));
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/zbx2000/p/12724916.html