疑问
暂无
代码
//注意精度
#include<cstdio>
#include<vector>
#include<algorithm>
#include<cmath>
using namespace std;
const int maxn = 100010;
struct node{
int depth;
int num;
vector<int> child;
}Node[maxn];
//输入结点数
int n=0;
//原始价格
double p=0;
//利润
double r=0;
//总价格
double sale=0;
void preOrder(int root,int depth){
Node[root].depth = 1+depth;
if(Node[root].child.size() == 0){
sale += Node[root].num * p * pow(1+r,Node[root].depth);
return;
}else{
for(int i=0;i<Node[root].child.size();i++){
preOrder(Node[root].child[i],Node[root].depth);
}
return;
}
}
int main(){
scanf("%d %lf %lf",&n,&p,&r);
r = r/100;
for(int i=0;i<n;i++){
int num;
scanf("%d",&num);
if(num != 0){
for(int j=0;j<num;j++){
int child;
scanf("%d",&child);
Node[i].child.push_back(child);
}
}else{
int n;
scanf("%d",&n);
Node[i].num = n;
}
}
preOrder(0,-1);
printf("%.1f",sale);
return 0;
}
反思
- 居然忘记了
scanf
怎么输入double
浮点数了,是使用%lf
,输出是使用%f
; - 一个非常重要的问题,看下面的代码:
//注意精度
//每个结点记录自己多少钱,反正空间不要钱
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int maxn = 100010;
struct node{
double price;
int num;
vector<int> child;
}Node[maxn];
//输入结点数
int n=0;
//原始价格
double p=0;
//利润
double r=0;
//总价格
double sale=0;
void preOrder(int root,double fprice){
Node[root].price = fprice * (1+r);
if(Node[root].child.size() == 0){
sale += Node[root].num * Node[root].price;
return;
}else{
for(int i=0;i<Node[root].child.size();i++){
preOrder(Node[root].child[i],Node[root].price);
}
return;
}
}
int main(){
scanf("%d %lf %lf",&n,&p,&r);
r = r/100;
for(int i=0;i<n;i++){
int num;
scanf("%d",&num);
if(num != 0){
for(int j=0;j<num;j++){
int child;
scanf("%d",&child);
Node[i].child.push_back(child);
}
}else{
int n;
scanf("%d",&n);
Node[i].num = n;
}
}
for(int i=0;i<Node[0].child.size();i++){
preOrder(Node[0].child[i],p);
}
printf("%.1f",sale);
return 0;
}
上述代码在每一步都直接计算了新的price,这样会在递归中使精度缺失,从而过不了测试用例1,参考《算法笔记》上的做法,应该要保存1+r
的幂,也就是递归的深度,最后再统一求price
,这样才不会确实精度。
二刷代码
- 二刷发现并没有发现有前面这个问题,难道是pat改了测试用例?
- 还是可以不使用结构体的
#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
using namespace std;
const int maxn = 1e5+10;
//依然使用简单表示的树
vector<int> child[maxn];
map<int,int> mp;
double ans=0.0;
double r;
void dfs(int root,double p){
if(child[root].size()==0){
ans += p*mp[root];
}else{
for(int i=0;i<child[root].size();i++){
dfs(child[root][i],p*(1+r));
}
}
}
int main(){
int n;
double p;
scanf("%d %lf %lf",&n,&p,&r);
r = r*0.01;
for(int i=0;i<n;i++){
int k;
scanf("%d",&k);
if(k==0){
int tot;
scanf("%d",&tot);
mp[i]=tot;
}else{
for(int j=0;j<k;j++){
int cur;
scanf("%d",&cur);
child[i].push_back(cur);
}
}
}
//cout<<"here"<<endl;
//采用dfs吧
dfs(0,p);
printf("%.1f",ans);
return 0;
}