藍橋杯-座次問題

DawnTraveler發表於2024-04-09

1.題目

題目描述

小 A 的學校,老師好不容易解決了藍橋杯的報名問題,現在老師又犯愁了。

現在有 N 位同學參加比賽,但是老師想給他們排座位,但是排列方式太多了。

老師非常想弄明白最後的排座次的結果是什麼樣子的,到底有多少種結果。

請設計一個程式幫助老師。

最後輸出各種情況的人名即可,一行一種情況,每種情況的名字按照報名即輸入順序排序。

輸入描述

輸入第一行包含一個整數 N。

接下來 N 行每行包含一個字串 Si ,表示人名。

\(1<=N<=10, \sum_{i=1}^n\mid S_i\mid<=\text{10}^2\)

輸出描述

輸出共若干行,每行輸出各種情況的人名。一行一種情況,每種情況的名字按照報名即輸入順序排序。

輸入輸出樣例

示例

輸入
3
xiaowang
xiaoA
xiaoli
copy

輸出
xiaowang xiaoA xiaoli
xiaowang xiaoli xiaoA
xiaoA xiaowang xiaoli
xiaoA xiaoli xiaowang
xiaoli xiaowang xiaoA
xiaoli xiaoA xiaowang

2. 題解

2.1 錯誤思路(使用next_permutation實現的全排列)

錯誤點

思路是對的,確實考的是全排列,但是這裡next_permutation是按位元組序排列,並非是按題目要求的輸入順序,導致錯誤

程式碼

#include<bits/stdc++.h>
using namespace std;

int factorial(int num){
	if (num == 1) return 1;
	return num * factorial(num - 1);
}

int main() {
	int n;
	cin >> n;
	vector<string> vec;
	for(int i = 0; i < n; i++) {
		string str;
		cin >> str;
		vec.push_back(str);
	}
	
	for(int i = 0; i < factorial(n); i++){
		for(string str : vec){
			cout << str << " ";
		}
		cout << endl;
		next_permutation(vec.begin(), vec.end());
	}
	return 0;
}

2.2 手動實現全排序(按輸入順序的)

思路

套用全排列模板即可

程式碼

#include<bits/stdc++.h>
using namespace std;
int n;
vector<string> vec;

string order[10]; 
bool chosen[10] = {false};

// x代表已選擇了x-1個 
void DFS(int x){
	// 已選擇完成 
	if(x == n) {
		for(int i = 0; i < n; i++){
			cout << order[i] << " ";
		}	
		cout << endl;
	}
	for(int i = 0; i < n; i++){
		// 該數已經被選擇過了,則跳過 
		if (chosen[i]) continue;
		else{
			// 選擇
			chosen[i] = true;
			order[x] = vec[i];
			DFS(x + 1); 
			// 不選擇 
			chosen[i] = false;
			order[x] = "";
		}
	}
} 

int main() {
	cin >> n;
	for(int i = 0; i < n; i++) {
		string str;
		cin >> str;
		vec.push_back(str);
	}
	
	DFS(0);
	return 0;
}