题目描述
题目描述见链接:https://www.patest.cn/contests/pat-a-practise/1079
题目分析
1.题目其实描述的是一个多叉树,根节点是0,对应的价格是p,每一层次对应的长度是r。
2.题目所要求的是叶子节点的价格*叶子节点的销售量
题目难点
1.分析完,就是建立一棵树,但是这个树是多叉树,因此不好建立。仔细分析后发现,并不需要建立一棵树,因为题目所要求的是路径,因此只需要存储叶子节点和叶子节点对应的父亲节点的编号。之后利用叶子节点的父亲节点是否为0,的循环,找到叶子节点的层次。见代码1
2.但是如果这么写,永远有一个(最后一个)案例超时,必须想别的办法。
3.因为是求层次,所以,用图(邻接表vector<vector<int> >
),不用树,用图的BFS算法,求出叶子节点的层次。
4.但是关于价格,首先要用price数组把对应的每一层的价格求出来,这样就会节省很多时间,不需要用pow函数。否则会超时。
题目代码1
#include <iostream>
#include <stdio.h>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
struct node{//结构体:节点编号,节点的父亲节点编号,节点的售卖量,节点的长度
int pid,id;
int value,len;
};
const int MAX = 100000+5;
node mynode[MAX];
double price[MAX];
int main(int argc, char *argv[]) {
int n;
double p,r,sum=0;
//cin>>n>>p>>r;
scanf("%d %lf %lf",&n,&p,&r);
if(n==1){//只有一个节点,即根节点,不乘(1+r/100)
int k,value;
cin>>k>>value;
sum = p*value;
printf("%.1lf",sum);
return 0;
}
for(int i=0;i<n;i++){//输入
int k;
cin>>k;
if(k==0){//如果是根节点的话,节点的长度为1,这样的话下面计算不会出错,否则少1
int value;
cin>>value;
mynode[i].value=value;//叶子节点,有售卖量,因此需要存储
mynode[i].len = 1;
}
else{
for(int j=0;j<k;j++){
int id;
cin>>id;
mynode[id].pid=i;
mynode[id].id = id;
mynode[id].value = 0;
}
}
}
//必须先计算出价格,不用math.pow()函数,否则会多次计算pow,效率降低
price[0]=p;
for(int i=1;i<n;i++){
price[i]=price[i-1]*(1+r/100);
}
//找叶子节点的层次,价格
for(int i=0;i<n;i++){
int value = mynode[i].value;
if(value!=0){
int pid = mynode[i].pid;
while(pid!=0){
mynode[i].len +=1;
pid = mynode[pid].pid;
}
int len = mynode[i].len;
sum += price[len]*value;
}
}
printf("%.1lf",sum);
return 0;
}
题目代码2
#include <iostream>
#include <stdio.h>
#include <vector>
#include <queue>
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
using namespace std;
struct node{
int id,value;
};
const int MAX= 100000+5;
int volumn[MAX]={0};//存储叶子节点的销售量
double price[MAX]={0};
vector< vector<int> > v(MAX);
double BFS(int n){//0是根节点,而且连通,不需要visited
//进行BFS(广度优先遍历)
int level = -1;
double ans=0;
queue<int> q;
q.push(n);
while(!q.empty()){
int size = q.size();
level++;
for(int i=0;i<size;i++){
int top=q.front();
q.pop();
int len = v[top].size();
if(len>0){//不是叶子节点,后续节点继续入队列
for(int j=0;j<len;j++){
q.push(v[top][j]);
}
}
else//是叶子节点
{
ans += price[level]*volumn[top];
}
}
}
return ans;
}
int main(int argc, char *argv[]) {
int n;
double p,r,sum=0;
cin>>n>>p>>r;
//计算价格,每层的价格
if(n==1){//只有一个节点,即根节点,不乘(1+r/100)
int k,value;
cin>>k>>value;
sum = p*value;
printf("%.1lf",sum);
return 0;
}
price[0]=p;
for(int i=1;i<n;i++){
price[i]=price[i-1]*(1+r/100);
}
for(int i=0;i<n;i++){
int k;
cin>>k;
if(k==0){//存储销售量
int vo;
cin>>vo;
volumn[i]=vo;
}
else{
for(int j=0;j<k;j++){//建立邻接表
int id;
cin>>id;
v[i].push_back(id);
}
}
}
printf("%.1f",BFS(0));
return 0;
}