1. 程式人生 > >PAT DS 4-09. 笛卡爾樹

PAT DS 4-09. 笛卡爾樹

簡單的問題不必複雜話,應該直接碼出來再說。

這題在printDirTree時打算用棧來儲存每層目錄,因為想著直接比較可能會比較費時。結果繞了一圈,發現還是直接比較簡單明瞭。

這題我的思路是,先qsort所有路徑,再輸出目錄樹。

qsort的比較函式要仔細思考,避免遺漏邊界(比如ab\cd\ 和ab\cd 的比較,ab\cd 和ab\c 的比較)。

輸出目錄樹主要是前後兩條路徑的比較,要記錄目錄層數和相同路徑的截止點。

<span style="font-size:18px;">#include <stdio.h>
#include <assert.h>
#include <stdbool.h>

#define NAME_SIZE 261
int n;

char input[10000][NAME_SIZE];

int nameCmp(const void *v1, const void *v2);
void printDirTree();

int main(void)
{
#ifdef DEBUG
	freopen("in.txt", "r", stdin);
#endif
	scanf("%d", &n);
	int i=0;
	for(; i<n; ++i)
		scanf("%s", *(input+i));
#ifdef DEBUG
	printf("\nOriginal data:\n");
	for(i=0; i<n; ++i)
		printf("%s\n", *(input+i));
#endif

	qsort(input, n, NAME_SIZE, nameCmp);
#ifdef DEBUG
	printf("\nqsorted data:\n");
	for(i=0; i<n; ++i)
		printf("%s\n", *(input+i));
#endif

	printDirTree();

	return 0;
}

int nameCmp(const void *v1, const void *v2)
{
#ifdef DEBUG
	//printf("in function nameCmp.\n");
#endif
	char *s1 = (char*)v1, *s2 = (char*)v2;
	int i=0;
	for(; s1[i]!=0 && s2[i]!=0; ++i){
		if(s1[i] == s2[i])
			continue;
		else if(s1[i] == '\\')
			return -1;
		else if(s2[i] == '\\')
			return 1;
		else
			break;
	}
	assert(s1[i] != s2[i]);
	if(s1[i] == 0 && s1[i-1] == '\\')
		return -1;
	if(s2[i] == 0 && s2[i-1] == '\\')
		return 1;
	int j=i;
	if(s1[j] < s2[j]){
		for(j=i; s1[j]!=0; ++j)
			if(s1[j] == '\\')
				return -1;
		for(j=i; s2[j]!=0; ++j)		// only if there's no directory in s1
			if(s2[j] == '\\')		// but is at least one directory in s2
				return 1;			// will return 1
		return -1;
	}
	if(s1[j] > s2[j]){
		for(j=i; s2[j]!=0; ++j)
			if(s2[j] == '\\')
				return 1;
		for(j=i; s1[j]!=0; ++j)
			if(s1[j] == '\\')
				return -1;
		return 1;
	}
}

void printOne(char *file, int depth, int dMark);

void printDirTree()
{
#ifdef DEBUG
	printf("\nOutput:\n");
#endif
	printf("root\n");

	printOne(input[0], 1, 0);
	int i = 1;
	for(; i<n; ++i){		// compare to the previous one and print
		int depth=1, dMark=-1;
		int j=0;
		for(; input[i][j]!=0 && input[i-1][j]!=0; ++j){
			if(input[i][j] == '\\'){
				++depth;
				dMark = j;
			}
			if(input[i][j] != input[i-1][j])
				break;
		}
#ifdef DEBUG
	//	printf("%s : %s\n", input[i-1], input[i]);
#endif
		assert(input[i][j] != 0 || (input[i][j]==0 && input[i-1][j]=='\\'));
		printOne(input[i], depth, dMark+1);
	}
}

void printOne(char *file, int depth, int dMark)
{
	assert(file[0] != '\\' && depth > 0 && dMark >= 0);
	char tmp[261];
	int i=dMark, k=0;
	for(; file[i] != 0; ++i, ++k){
		if(file[i] == '\\'){
			tmp[k] = 0;
			for(k=0; k<depth; ++k)
				printf("  ");
			printf("%s\n", tmp);

			++depth;
			k=-1;
			continue;
		}
		tmp[k] = file[i];
	}
	if(k > 0){
		tmp[k] = 0;
		for(k=0; k<depth; ++k)
			printf("  ");
		printf("%s\n", tmp);
	}
}</span>


相關推薦

PAT DS 4-09.

簡單的問題不必複雜話,應該直接碼出來再說。 這題在printDirTree時打算用棧來儲存每層目錄,因為想著直接比較可能會比較費時。結果繞了一圈,發現還是直接比較簡單明瞭。 這題我的思路是,先qsort所有路徑,再輸出目錄樹。 qsort的比較函式要仔細思考,避免遺漏邊界(

POJ-1785-Binary Search Heap Construction()

org fine sig b- popu arc basic define 卡爾 Description Read the statement of problem G for the definitions concerning trees. In the foll

[COGS 2421] [HZOI 2016] 簡單的Treap

printf 搜索樹 images for bsp lin 維護 區間 stdout 笛卡爾樹就是你給兩維限制,一維堆R,一維二叉搜索樹K,平地拔起一棵Treap,最廣範的應用:用LCA求區間最值,建Treap,還有個什麽範圍top k我表示並不會查都查不到。它最妙最高的地

【BZOJ2616】SPOJ PERIODNI +樹形DP

方法 logs pac 題解 ring pri -i nbsp 表示 【BZOJ2616】SPOJ PERIODNI Description Input 第1行包括兩個正整數N,K,表示了棋盤的列數和放的車數。 第2行包含N個正整數,表示了棋盤每列的高

筆記:

.cn item net inf logs http alt details cnblogs 笛卡爾樹 參考文章 https://baike.baidu.com/item/%E7%AC%9B%E5%8D%A1%E5%B0%94%E6%A0%91/7579802?fr=ala

的妙用

兩個 進棧 二叉 clas sta 擁有 logs 查找 一個 前言 笛卡爾樹,其實是一顆treap,每個節點擁有兩個值,key值和val值。key值是這個節點本身的大小值,在一顆treap中滿足二叉查找樹的性質,而val值則是一個隨機值,學過treap的同學都知道,這個v

HDU - 6305 RMQ Similar Sequence(

std ans problem image clu tree ons mat nod http://acm.hdu.edu.cn/showproblem.php?pid=6305 題目 對於A,B兩個序列,任意的l,r,如果RMQ(A,l,r)=RMQ(B,l,r),

51nod 1102 面積最大的矩形 ()

之前用的單調棧解決的,這次發現了一個新方法 笛卡爾樹,記錄一下 #include<cstdio> #include<cstring> #include<iostream> using namespace std; const int maxn=100

7-8 (25 分)

7-8 笛卡爾樹 (25 分) 笛卡爾樹是一種特殊的二叉樹,其結點包含兩個關鍵字K1和K2。首先笛卡爾樹是關於K1的二叉搜尋樹,即結點左子樹的所有K1值都比該結點的K1值小,右子樹則大。其次所有結點的K2關鍵字滿足優先佇列(不妨設為最小堆)的順序要求,即該結點的K2值比其子樹

演算法合集 | 神奇的

        笛卡爾樹是一個很有意思的樹形結構,因為它同時滿足兩個性質,從key(key就是索引位置,如下圖中9的key為1,3的key為2......)來看,滿足二叉搜尋樹的特性,從value來看,滿足堆的性質。         重點參考下圖,圖片來自維基百科,

正睿2019省選十連測day3T3(,dp)

題面描述 有一個11到nn的排列p1,p2,p3,…,pn,你會對它進行若干輪操作,每一輪操作,你會保留序列中極大的數,也就是說對於每個數字,如果它比相鄰的數字都大,那麼會被保留下來。比如一個排列(3,2,5,1,4,6),經過一輪操作之後序列變成(3,5,6),第二輪操作之後

POJ 2559-Largest Rectangle in a Histogram 解題報告 【與單調棧】

POJ 2559-Largest Rectangle in a Histogram 解題報告 【笛卡爾樹與單調棧】 Description   A histogram is a polygon composed of a sequence of rectang

[BZOJ]5042: LWD的分科島 +LCA

Description 大家都知道在文理分科的時候總是讓人糾結的,糾結的當然不只是自己。比如 YSY 就去讀了文科, LWD 知道了很氣。於是他就去卡了 BZOJ 測評機, 晚上他做了一個謎一樣的夢,自己在一座全是 YSY 的分科島。這裡有 YSY 草, YSY 花, YSY 糖……

簡介(分類到treap裡面)

構造笛卡爾樹的過程: 使用資料結構棧,棧中儲存的始終是右鏈,即根結點、根結點的右兒子、根結點的右兒子的右兒子……組成的鏈 並且棧中從棧頂到棧底key依次減小 如果按照從後到前的順序判斷一個元素是否大於A[i],則每次插入的時間複雜度為O(k+1) k為本次插入中移除的右鏈元素個數。因為每個元素最多進出右鏈各

[轉載] Cartesian Tree

這篇寫的太好了,看了好幾個碼的,都寫的不知所云,就這個思路最清晰   笛卡爾樹Cartesian Tree   前言 最近做題目,已經不止一次用到笛卡爾樹了。這種資料結構極為優秀,但是構造的細節很容易出錯。因此寫一篇文章做一個總結。 笛卡爾樹&n

(Cartesian Tree)

  笛卡爾樹是一棵二叉樹,樹的每個節點有兩個值,一個為index,一個為value。光看index的話,笛卡爾樹是一棵二叉搜尋樹,每個節點的左子樹的index都比它小,右子樹都比它大;光看value的話,笛卡爾樹有點類似堆,根節點的value是最小(或者最大)的

hdu 4605 Magic Ball Game(可持久化

題目大意 給定一棵二叉樹,保證節點沒有孩子節點或者有兩個孩子節點,並且每個節點有一個權值W[i],1為根節點,樹給定的方式m個關係u a b,表示u節點的左孩子為a,右孩子為b。現在從根節點放一個權值為X的小球: - X = W[u]時:小球停留在該

51nod 1934 受限制的排列——

.com class urn scan int r+ per push 這樣的 題目:http://www.51nod.com/Challenge/Problem.html#!#problemId=1934 根據給出的信息,可以遞歸地把笛卡爾樹建出來。一個點只應該有 0/1

HDU - 1506 Largest Rectangle in a Histogram (單調棧/)

return col 一道 scan 卡爾 左右 build new \n 題意:求一個直方圖中最大矩形的面積。 很經典的一道問題了吧,可以用單調棧分別求出每個柱子左右兩邊第一個比它低的柱子(也就相當於求出了和它相連的最後一個比它高的柱子),確定每個柱子的左右邊界,每個柱

TopCoder 14084 BearPermutations2【+dp】

d+ -- code sum turn topcoder long long memset opcode 傳送:https://vjudge.net/problem/TopCoder-14084 只是利用了笛卡爾樹的性質,設f[i][j]為區間[i,j]的貢獻,然後枚舉中間