【蓝桥必胜】试题 算法训练 数字游戏-全排列搜索

文章目录

题目

资源限制
时间限制:1.0s 内存限制:256.0MB

问题描述

给定一个1~N的排列a[i],每次将相邻两个数相加,得到新序列,再对新序列重复这样的操作,显然每次得到的序列都比上一次的序列长度少1,最终只剩一个数字。
例如:

3 1 2 4
 4 3 6
  7 9
  16

现在如果知道N和最后得到的数字sum,请求出最初序列a[i],为1~N的一个排列。若有多种答案,则输出字典序最小的那一个。数据保证有解。

输入格式

第1行为两个正整数n,sum

输出格式

一个1~N的一个排列

样例输入

4 16

样例输出

3 1 2 4

数据规模和约定

0<n<=10

解析

直接通过全排列暴力搜索,由于Java中没有提供全排列函数 next_permutation,所以要自己实现。注意实现全排列的时候的每个排列之间要满足升序,从而贪心的达到结果的字典序最小。

代码

// 数字游戏
import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		
		int n = scanner.nextInt();
		int sum = scanner.nextInt();
		int array[] = new int[n];
		
		for (int i=0; i<n; i++) {
			array[i] = i+1;
		}
		
		do {
			int temp[] = new int[n];
			System.arraycopy(array, 0, temp, 0, array.length);
            // 计算每次生成的排列的最后得到的数字
			for(int i=0; i<temp.length-1; i++) {
				for(int j=0; j<temp.length-i-1; j++) {
					temp[j] = temp[j] + temp[j+1];
				}
			}
            // 如果最后得到的数字等于sum,则输出结果
			if (temp[0] == sum) {
				for (int i=0; i<array.length; i++) {
					System.out.print(array[i] + " ");
				}
				break;
			}
			
		} while(next_permutation(array));
		
		scanner.close();
	}
	public static boolean next_permutation(int[] array) {
		if(array.length <= 1) {
			return false;
		}
		
		int i = array.length-2;
		// 寻找第一个不满足降序的数
		while (i>=0 && array[i]>array[i+1]) {
			i--;
		}
		if (i == -1) {
			return false;
		}
		
		// 寻找大于 array[i] 的最小的数,作交换
		int j = i + 1;
		while (j<array.length && array[j]>array[i]) {
			j++;
		}
		swap(array, i, j-1);
		// 对 i 后的数排序
		Arrays.sort(array, i+1, array.length);
		
		return true;
	}
	public static void swap(int[] array, int i, int j) {
		int temp = array[i];
		array[i] = array[j];
		array[j] = temp;
	}
}

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码
< <上一篇
下一篇>>