1. 程式人生 > >hiho220 Push Button I

hiho220 Push Button I

時間限制:5000ms

單點時限:1000ms

記憶體限制:256MB

描述

There are N buttons on the console. Each button needs to be pushed exactly once. Each time you may push several buttons simultaneously.

Assume there are 4 buttons. You can first push button 1 and button 3 at one time, then push button 2 and button 4 at one time. It can be represented as a string "13-24". Other pushing ways may be "1-2-4-3", "23-14" or "1234". Note that "23-41" is the same as "23-14".

Given the number N your task is to find all the pushing ways.

輸入

An integer N. (1 <= N <= 8)

輸出

Output the different pushing ways in lexicographical order.

For the same pushing way output the smallest string in lexicographical order as representative.

樣例輸入

3

樣例輸出

1-2-3
1-23
1-3-2
12-3
123
13-2
2-1-3
2-13
2-3-1
23-1
3-1-2
3-12
3-2-1

題意分析:

1.題是什麼?

    給你個數字n,1<=n<=8,字典序升序輸出由1到n的數字和符號'-'構成的所有字串,要求不能重複,這個重複指的是由'-'隔開的數字集合不能重複,32和23就是重複的.

2.思路

    首先看到是按字典序輸出所有字串可能,妥妥的dfs填空,我們知道關於最簡單的字串字典序升序我們做一個flag陣列記錄哪些字元用過的即可,然後每層遞迴都由一個for迴圈由字典序升序逐個填入每個可用字元即可升序構造出所有不重複的字串,

int rest;
void dfs(int nowpos){
	if(!rest){
		ans[nowpos]='\0'; 
		puts(ans);
		return;
	}
	for(int i=1;i<=n;i++){
		if(flag[i]){
			ans[nowpos]='0'+i;
			flag[i]=false;
			rest--;
			
			dfs(nowpos+1);
			
			rest++;
			flag[i]=true;
		}
	}
}

現在這個問題加深了難度,加入了一個'-'符號並且重定義了重複,認為兩個字串中每個'-'分隔開的部分都包含完全相同的字符集即視為重複

比如 12-34 與21-43也是重複的,故而我們對dfs需要做修改,一方面加入'-',一方面加入另一個標誌位interrupt

'-'的規則很簡單,不是第一個且前面也不是'-'則優先dfs填入,

而interrupt的設計目的是保證'-'所隔開的分塊內字元為升序,interrupt存的值為當前分塊內最大的字元,故而自然填入新的'-'即開始新的分塊時要重置為0,填入新字元時更新interrupt,for迴圈也以interrupt對i做初始化;

ac程式碼

#include <stdio.h>
const int maxn=9;
int n;
char ans[2*maxn];
bool flag[maxn];
int rest;
int interrupt;
void dfs(int nowpos){
	if(!rest){
		ans[nowpos]='\0';//手動結尾,很重要 
		puts(ans);
		return;
	}
	if(nowpos&&ans[nowpos-1]!='-'){//不是第一個空並且前面不是'-' 
		ans[nowpos]='-';
		//修改標誌 
		int temp=interrupt;
		interrupt=0;
		
		dfs(nowpos+1);
		//回溯標誌 
		interrupt=temp;
	}
	for(int i=interrupt+1;i<=n;i++){
		if(flag[i]){
			ans[nowpos]='0'+i;
			
			//修改標誌 
			flag[i]=false;
			rest-=1;
			int temp=interrupt;
			interrupt=i;
			
			dfs(nowpos+1);
			
			//回溯標誌 
			interrupt=temp; 
			rest+=1;
			flag[i]=true;
		}
	}
}
int main(){
	scanf("%d",&n);
	rest=n;
	interrupt=0;
	for(int i=1;i<=n;i++) flag[i]=true; 
	dfs(0);
	return 0;
}