1. 程式人生 > >經典題:求字典序第m個的序列(2062)

經典題:求字典序第m個的序列(2062)

Subset sequence

Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4587    Accepted Submission(s): 2228


Problem Description Consider the aggregate An= { 1, 2, …, n }. For example, A1={1}, A3={1,2,3}. A subset sequence is defined as a array of a non-empty subset. Sort all the subset sequece of An in lexicography order. Your task is to find the m-th one.

Input The input contains several test cases. Each test case consists of two numbers n and m ( 0< n<= 20, 0< m<= the total number of the subset sequence of An ).
Output For each test case, you should output the m-th subset sequence of An in one line.
Sample Input 1 1 2 1 2 2 2 3 2 4 3 10
Sample Output 1 1 1 2 2 2 1 2 3 1

設f[i]為1到n的排成的序列的總數,則可由打表發現:f[i]=n*(f[i-1]+1),這裡其實蘊含著遞迴的思想。我們想要知道序列的具體位置,由規律性:zushu=ceil(m*1.0/(f[n-1]+1)),然後就可以取出首位元素了,剩下的序列可由遞迴求解,同時,原序列需要更新,元素被取出。然後就要更新內層的組數了:m=m-(zushu-1)*(f[n-1]+1)-1,因為每個序列的最小的那一個就一個元素,其後沒有元素,所以需要-1。n還需自減一次。

/*------------------Header Files------------------*/
#include <iostream>
#include <cstring>
#include <string>
#include <cstdio>
#include <algorithm>
#include <cstdlib>
#include <ctype.h>
#include <cmath>
#include <stack>
#include <queue>
#include <deque>
#include <map>
#include <vector>
#include <limits.h>
using namespace std;
/*------------------Definitions-------------------*/
#define LL long long
#define PI acos(-1.0)
#define INF 0x3F3F3F3F
#define MOD 10E9+7
#define MAX 500050
/*---------------------Work-----------------------*/

void work()
{
	int n;
	LL m,f[25];
	f[0]=0;
	for(int i=1;i<=20;i++)
		f[i]=i*(f[i-1]+1);
	while(scanf("%d%I64d",&n,&m)==2)
	{
		int num[25];
		for(int i=1;i<=n;i++)
			num[i]=i;
		bool flag=true;
		while(m>0)
		{
			int zushu=ceil(m*1.0/(f[n-1]+1)); //計算所屬組數
			if(!flag) printf(" ");
			flag=false;
			printf("%d",num[zushu]);
			for(int i=zushu;i<n;i++) //合併掉這個位置
				num[i]=num[i+1];
			m=m-(zushu-1)*(f[n-1]+1)-1; //-1是因為第一個只有一個數字
			n--;
		}
		printf("\n");
	}
}
/*------------------Main Function------------------*/
int main()
{
	//freopen("test.txt","r",stdin);
	//freopen("cowtour.out","w",stdout);
	//freopen("cowtour.in","r",stdin);
	work();
	return 0;
}


相關推薦

經典字典m序列(2062)

Subset sequence Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 4587    Accepte

單向連結串列倒m元素

   原題為某遊戲公司試題,大意如下:對於一個單向連結串列,試寫出找到它的倒序第m個元素(m >= 1)的函式,注意變數命名、註釋、時間複雜度、空間複雜度。注:要求寫出可編譯並可以執行通過的程式程式碼。  這道題的常規做法或者說首先想到直覺的方法M1是先求得連結串列的長度,即元素總個數n,然

SUBLEX Lexicographical Substring Search 字典k小的子串

題目:求字串字典序第k小的子串 思路:統計每個狀態的子串的個數,按字典序尋找 程式碼: #pragma comment(linker, "/STACK:1024000000,1024000000") #include<iostream> #include<

SPOJ Lexicographical Substring Search 字典k大子串 後綴自動機

scan span ogr set mes cin () spa bit 題目傳送門 思路:按字典序,小的字符優先選取。對於一個字符,如果以這個字符開頭的子串大於等於k個,那說明這個字符是應該選的,並且選完之後,可能還要繼續選。如果以這個字符開頭的子串小於k個,說明這個字

MOOC北京理工《C語言程式設計(上)》5周3最小m

題目內容: 求滿足下列不等式的最小 m。     1 + 2 + 3 + 4 + ...... + m ≥ n 例如:n=100,當 m =14 時,滿足:1+2+3+4+...+13=91<100,而 1+2+3+4+......+14=105>100

給定整數n和m, 將1到n的這n整數按字典排列之後, 其中的m個數。

自己構造了一個map,自定義了map的比較函式,程式碼通過率為50%,不知道為什麼這樣的複雜度還不能通過?程式碼如下#include <iostream> #include <vector> #include <map> #include

A+B

題目,求A+B,每一行將包含兩個整數A和B程序到檔案結束。對於每種情況,在一行中輸出A+B。 題解:輸入A.B,再建立迴圈,直到不再輸入時停止,輸出A+B #include <iostream> using namespace std; int main() { int a

眾數

問題描述 給定一個大小為 n 的陣列,找到其中的眾數。眾數是指在陣列中出現次數大於 ⌊ n/2 ⌋ 的元素。 你可以假設陣列是非空的,並且給定的陣列總是存在眾數。 示例 1: 輸入: [3,2,3] 輸出: 3 示例 2: 輸入: [2,2,1,1,1,2,2] 輸出:

LeetCode——二叉樹深度

題目: 給定一個二叉樹,找出其最大深度。 二叉樹的深度為根節點到最遠葉子節點的最長路徑上的節點數。 說明: 葉子節點是指沒有子節點的節點。 示例: 給定二叉樹 [3,9,20,null,n

【雙向bfs(一次可也)】【非簡單圖的最短路】UVa1599 Ideal Path 【紫書6-20經典例題】【無向圖字典最小的最短路】

【雙向bfs(一次也可)】【非簡單圖的最短路】UVa1599 Ideal Path 【紫書6-20經典例題】【無向圖求字典序最小的最短路】 New labyrinth attraction is open in New Lostland amusement p

演算法N!末尾0的個數和二進位制數中1的個數

1、給定一個整數,那麼N的階乘N!末尾有多少個0呢? 解題思路:N!=K*10^M,M的值即為N!末尾0的個數。又10^M=(2^M)*(5^M),因為一個數進行質因數分解後,2出現的概率比5大得多。所以只有計算出1到N包含多少個5的因子 public class demo2 {

一道簡單的演算法不借助三變數來交換兩變數的值

今天做筆試碰到一道簡單的演算法題:不借助第三變數來交換兩個變數的值,記錄一下。 交換兩個變數的值的普遍做法都是藉助第三變數,這樣具有較高的可讀性。 a = 3 b = 5 t = a a = b b = t 但是,如果記憶體有限,只允許用2個變數呢? 強大的CS當然有辦法解決

演算法與設計經典大整數乘法(教材2-4)

給定兩個整數u和v,他們分別有m和n為數字,且m≤n,用通常的乘法求uv的值需要O(mn)時間,可以將u和v均看作是有n位數字的大整數,用本章介紹的分治法,在O(n^(log3))時間內計算uv的值,當m<<n時,此法效率不高。設計演算法在O(nlog2/3)時間計算uv的值 在O(

BZOJ3994約數個數和(莫比烏斯反演[1,N]*[1,M]的矩陣的因子個數)

Description  設d(x)為x的約數個數,給定N、M,求   Input 輸入檔案包含多組測試資料。 第一行,一個整數T,表示測試資料的組數。 接下來的T行,每行兩個整數N、M。 Ou

給兩字串(都是大寫字母,且長的相等) 字典在這兩字串之間的一個等長字串

 題目有點坑,要仔細想想(水題一道) #include<iostream> #include<cstring> #include<algorithm> using namespace std; int main() { string a,b,

C語言——素數和——n素數到m素數之間所有的素數的和,包括n素數和m素數

程式的邏輯性很關鍵,首先想好分幾步走,每一步定義什麼,輸出什麼結果 OK想好了,開始吧 #include<stdio.h> int main() {//1.0初始化結果變數n,m int n,m,result=0; scanf("%d %d",&n,&m)

模擬 P1030 排列 洛谷 簡單

題目描述 給出一棵二叉樹的中序與後序排列。求出它的先序排列。(約定樹結點用不同的大寫字母表示,長度 \le 8≤8)。 輸入輸出格式 輸入格式: 22行,均為大寫字母組成的字串,表示一棵二叉樹的中序與後序排列。 輸出格式: 11行,表示一棵二叉樹的先序。 輸入輸出樣例 輸入樣例#

JavaMN素數之間的素數和

題目內容: 我們認為2是第一個素數,3是第二個素數,5是第三個素數,依次類推。 現在,給定兩個整數n和m,0<n<=m<=200,你的程式要計算第n個素數到第m個素數之間所有的素數的和,包括第n個素數和第m個素數。 注意,是第n個素數到第m個素

三道習題(1、將單詞表中由相同字母組成的單詞歸成一類,每類單詞按照單詞的首字母排序,並按 #每類中第一單詞字典序由大到小排列輸出各個類別。 #輸入格式字典序由小到大輸入若干單詞,每個單詞佔一行,以end結束輸入。)

#coding=gbk ''' 1、將單詞表中由相同字母組成的單詞歸成一類,每類單詞按照單詞的首字母排序,並按 #每類中第一個單詞字典序由大到小排列輸出各個類別。 #輸入格式:按字典序由小到大輸入若干個單詞,每個單詞佔一行,以end結束輸入。 #cinema #iceman #maps #spam #a

給兩字串(都是大寫字母,且長的相等) 字典在這兩字串之間的一個等長字串

 題目有點坑,要仔細想想(水題一道) #include<iostream> #include<cstring> #include<algorithm> using namespace std; int main() { strin