1. 程式人生 > >PAT-ADVANCED1079——Total Sales of Supply Chain

PAT-ADVANCED1079——Total Sales of Supply Chain

我的PAT-ADVANCED程式碼倉:https://github.com/617076674/PAT-ADVANCED

原題連結:https://pintia.cn/problem-sets/994805342720868352/problems/994805388447170560

題目描述:

題目翻譯:

1079 供應鏈總銷售額

供應鏈是零售商,經銷商和供應商構成的網路 - 每個人都參與將產品從供應商轉移到客戶。從一個根供應商開始,鏈上的每個人都以價格P從一個供應商處購買產品,並以高於P的r%的價格出售或分銷它們。只有零售商才會面對客戶。 假設供應鏈中的每個成員除了根供應商之外只有一個供應商,並且沒有供應環。現在給定供應鏈,您需要給出所有零售商中的最高價格。

輸入格式:

每個輸入檔案包含一個測試用例。在每個測試用例中,第一行包含3個正整數:N(<= 10 ^ 5),供應鏈中的總節點數(節點編號為0 ~ N - 1,根結點編號為0);P,代表商品的單位價格;以及r,代表每個經銷商或零售商的價格增量百分比。接下來的N行,每行以下述形式描述一個經銷商或零售商:

K​i​​ ID[1] ID[2] ... ID[K​i​​]

在第i行,Ki代表的是從供應點i進貨的經銷商或零售商數量,緊跟著的是這些經銷商或零售商的ID。Kj等於0時,表示第j號節點是一個零售商,其後的數字代表該零售商賣出的商品總數。一行中的所有數字以一個空格分隔。

輸出格式:

對每個測試用例,輸出所有零售商的銷售總額,結果精確到小數點後1位。題目保證這個數字不會超過10 ^ 10。

輸入樣例:

10 1.80 1.00
3 2 3 5
1 9
1 4
1 7
0 7
2 6 1
1 8
0 9
0 4
0 3

輸出樣例:

42.4

知識點:樹的深度優先遍歷、樹的廣度優先遍歷

思路一:深度優先遍歷的同時記錄節點的層級

用printf函式的格式化輸出“%.1lf”,會自動幫我們四捨五入。

時間複雜度和空間複雜度均是O(N)。

C++程式碼:

#include<iostream>
#include<vector>
#include<math.h>

using namespace std;

struct node{
	int sales;
	vector<int> child;
};

int N;
double P;
double r;
node Node[100000];
double totalSales = 0.0;

void dfs(int nowVisit, int level);

int main(){
	cin >> N >> P >> r;
	int K, num;
	for(int i = 0; i < N; i++){
		cin >> K;
		if(K == 0){
			cin >> num;
			Node[i].sales = num; 
		}else{
			for(int j = 0; j < K; j++){
				cin >> num;
				Node[i].child.push_back(num);
			}
		}
	}
	dfs(0, 0);
	printf("%.1lf\n", totalSales);
	return 0;
}

void dfs(int nowVisit, int level){
	if(Node[nowVisit].child.size() == 0){
		totalSales += Node[nowVisit].sales * P * pow(1.0 + r / 100, level);
		return;
	}
	for(int i = 0; i < Node[nowVisit].child.size(); i++){
		dfs(Node[nowVisit].child[i], level + 1);
	}
}

C++解題報告:

思路二:廣度優先遍歷的同時為每個幾點新增層級資訊且判別是否是葉子節點

時間複雜度和空間複雜度均是O(N)。

C++程式碼:

#include<iostream>
#include<vector>
#include<math.h>
#include<queue>

using namespace std;

struct node{
	int sales;
	int level;
	vector<int> child;
};

int N;
double P;
double r;
node Node[100000];
double totalSales = 0.0;

void bfs(int nowVisit);

int main(){
	cin >> N >> P >> r;
	int K, num;
	for(int i = 0; i < N; i++){
		cin >> K;
		if(K == 0){
			cin >> num;
			Node[i].sales = num; 
		}else{
			for(int j = 0; j < K; j++){
				cin >> num;
				Node[i].child.push_back(num);
			}
		}
	}
	bfs(0);
	printf("%.1lf\n", totalSales);	//自動四捨五入 
	return 0;
}

void bfs(int nowVisit){
	queue<int> q;
	Node[nowVisit].level = 0;
	q.push(nowVisit);
	while(!q.empty()){
		int now = q.front();
		if(Node[now].child.size() == 0){
			totalSales += Node[now].sales * P * pow(1.0 + r / 100, Node[now].level);
		}
		q.pop();
		for(int i = 0; i < Node[now].child.size(); i++){
			Node[Node[now].child[i]].level = Node[now].level + 1;
			q.push(Node[now].child[i]);
		}
	}
}
void dfs(int nowVisit, int level){
	if(Node[nowVisit].child.size() == 0){
		
		return;
	}
	for(int i = 0; i < Node[nowVisit].child.size(); i++){
		dfs(Node[nowVisit].child[i], level + 1);
	}
}

C++解題報告: