数据结构(陈越) 作业题 第三周

03-1. 二分法求多项式单根

时间限制

400 ms

内存限制

65536 kB

代码长度限制

8000 B

判题程序

Standard

作者

杨起帆(浙江大学城市学院)

二分法求函数根的原理为:如果连续函数f(x)在区间[a, b]的两个端点取值异号,即f(a)f(b)<0,则它在这个区间内至少存在1个根r,即f(r)=0。

二分法的步骤为:

  • 检查区间长度,如果小于给定阈值,则停止,输出区间中点(a+b)/2;否则
  • 如果f(a)f(b)<0,则计算中点的值f((a+b)/2);
  • 如果f((a+b)/2)正好为0,则(a+b)/2就是要求的根;否则
  • 如果f((a+b)/2)与f(a)同号,则说明根在区间[(a+b)/2, b],令a=(a+b)/2,重复循环;
  • 如果f((a+b)/2)与f(b)同号,则说明根在区间[a, (a+b)/2],令b=(a+b)/2,重复循环;

    本题目要求编写程序,计算给定3阶多项式f(x)=a3x3+a2x2+a1x+a0在给定区间[a, b]内的根。

    输入格式:

    输入在第1行中顺序给出多项式的4个系数a3、a2、a1、a0,在第2行中顺序给出区间端点a和b。题目保证多项式在给定区间内存在唯一单根。

    输出格式:

    在一行中输出该多项式在该区间内的根,精确到小数点后2位。

    输入样例:

    3 -1 -3 1
    -0.5 0.5
    

    输出样例:

    0.33

此题比较简单,有两个点要注意。

1.输入完之后,应该先判断两个端点是否是根,如果是直接输出,否则再用二分法来查找

2.输出时精确到小数点后2位,所以应该保证精确解和近似解相差不超0.001,所以循环终止条件为找到根,或者|b-a|<0.001

 1 //一是如何判断精度,二是如何设置输出的小数点后位数
 2 #include<iostream>
 3 #include<iomanip>
 4 using namespace std;
 5
 6 double a[4];
 7 double f(double);
 8
 9 int main()
10 {
11     cin >> a[0] >> a[1] >> a[2] >> a[3];
12
13     double a,b;
14     cin >> a >> b;
15
16     double left=a,right=b,mid=(a+b)/2.0;
17
18     if (f(left)==0.)
19         cout << fixed << setprecision(2) << left << endl;
20     else if (f(right)==0.)
21         cout << fixed << setprecision(2) << right << endl;
22     else
23     {
24         while (  f(mid) && (right-left)>0.001 )
25         {
26             if ( f(left)*f(mid) < 0 )
27                 right = mid;
28             else
29                 left = mid;
30             mid = (left+right)/2.0;
31         }
32         cout << fixed << setprecision(2) << mid << endl;
33     }
34
35     return 0;
36 }
37
38 double f (double x)
39 {
40     double results=a[0]*x+a[1];
41
42     for (int i=2;i<4;i++)
43     {
44         results = results*x+a[i];
45     }
46     return results;
47 }

03-2. List Leaves

时间限制

400 ms

内存限制

65536 kB

代码长度限制

8000 B

判题程序

Standard

作者

CHEN, Yue

Given a tree, you are supposed to list all the leaves in the order of top down, and left to right.

Input Specification:

Each input file contains one test case. For each case, the first line gives a positive integer N (<=10) which is the total number of nodes in the tree -- and hence the nodes are numbered from 0 to N-1. Then N lines follow, each corresponds to a node, and gives the indices of the left and right children of the node. If the child does not exist, a "-" will be put at the position. Any pair of children are separated by a space.

Output Specification:

For each test case, print in one line all the leaves‘ indices in the order of top down, and left to right. There must be exactly one space between any adjacent numbers, and no extra space at the end of the line.

Sample Input:

8
1 -
- -
0 -
2 7
- -
- -
5 -
4 6

Sample Output:

4 1 5

本题的第一个关键点是,如何找出树的根结点。很简单,输入的每一行分别是每个结点的左右孩子,因此输入中不出现的那个结点就是根结点,很容易理解。输入完之后构建树,构建完之后用队列进行层序遍历,输出的条件是判断结点是叶结点。
 1 #include<iostream>
 2 #include<fstream>
 3 #include<queue>
 4 using namespace std;
 5
 6 struct node
 7 {
 8     int data;
 9     node* left;
10     node* right;
11 };
12
13 int main()
14 {
15     int N;
16     char left,right;
17     cin >> N;
18
19     node **tree = new node* [N];
20     int *flag = new int [N];
21
22     for (int i=0;i<N;i++)
23     {
24         tree[i] = new node;
25         tree[i]->data = i;
26         flag[i]=1;
27     }
28
29     for (int i=0;i<N;i++)
30     {
31         cin >> left;
32         if (left == ‘-‘)
33             tree[i]->left = nullptr;
34         else
35         {
36             tree[i]->left = tree[left-‘0‘];
37             flag[left-‘0‘]=0;
38         }
39
40         cin >> right;
41         if (right == ‘-‘)
42             tree[i]->right = nullptr;
43         else
44         {
45             tree[i]->right = tree[right-‘0‘];
46             flag[right-‘0‘]=0;
47         }
48     }
49
50     int head=0;
51     for (int i=0;i<N;i++)
52         if (flag[i] == 1)
53             head = i;
54
55     //开始层序遍历输出叶节点
56     queue<node*> Q;
57     Q.push(tree[head]);
58     node *temp_node;
59     int output_flag=0;
60
61     while (!Q.empty())
62     {
63         temp_node = Q.front();
64         Q.pop();
65         if (!temp_node->left && !temp_node->right )
66         {
67             if (output_flag)
68                 cout << ‘ ‘ << temp_node->data;
69             else
70             {
71                 cout << temp_node->data;
72                 output_flag=1;
73             }
74         }
75
76         if (temp_node->left)
77             Q.push(temp_node->left);
78         if (temp_node->right)
79             Q.push(temp_node->right);
80     }
81
82     return 0;
83 }

03-3. Tree Traversals Again

时间限制

200 ms

内存限制

65536 kB

代码长度限制

8000 B

判题程序

Standard

作者

CHEN, Yue

An inorder binary tree traversal can be implemented in a non-recursive way with a stack. For example, suppose that when a 6-node binary tree (with the keys numbered from 1 to 6) is traversed, the stack operations are: push(1); push(2); push(3); pop(); pop(); push(4); pop(); pop(); push(5); push(6); pop(); pop(). Then a unique binary tree (shown in Figure 1) can be generated from this sequence of operations. Your task is to give the postorder traversal sequence of this tree.

Figure 1

Input Specification:

Each input file contains one test case. For each case, the first line contains a positive integer N (<=30) which is the total number of nodes in a tree (and hence the nodes are numbered from 1 to N). Then 2N lines follow, each describes a stack operation in the format: "Push X" where X is the index of the node being pushed onto the stack; or "Pop" meaning to pop one node from the stack.

Output Specification:

For each test case, print the postorder traversal sequence of the corresponding tree in one line. A solution is guaranteed to exist. All the numbers must be separated by exactly one space, and there must be no extra space at the end of the line.

Sample Input:

6
Push 1
Push 2
Push 3
Pop
Pop
Push 4
Pop
Pop
Push 5
Push 6
Pop
Pop

Sample Output:

3 4 2 6 5 1
这题我的做法是,根据输入中的操作和序号,来构建树。从第一个操作开始,相邻的两个操作有4种可能,push-push,push-pop,pop-pop,pop-push,根据这四种可能来构建树。构建完之后用后序遍历输出即可。值得注意的是,后序遍历可以递归,可以非递归,建议大家两种都写一下,让自己更熟悉。我自己第一遍写后序遍历的非递归程序的过程就比较麻烦了。
  1 #include<string>
  2 #include<stack>
  3 #include<iostream>
  4 #include<fstream>
  5 using namespace std;
  6
  7 struct node
  8 {
  9     int data;
 10     node *left;
 11     node *right;
 12     int flag;
 13 };
 14
 15 int main()
 16 {
 17     int N;
 18     cin >> N;
 19
 20     string *operation = new string [N*2];
 21     int *num = new int [N*2];
 22     string temp_op;
 23
 24     for (int i=0;i<2*N;i++)
 25     {
 26         cin >> temp_op;
 27         if (temp_op == "Push")
 28         {
 29             operation[i] = "Push";
 30             cin >> num[i];
 31         }
 32         else
 33         {
 34             operation[i] = "Pop";
 35             num[i]=-1;
 36         }
 37     }
 38
 39     node **tree = new node* [N+1];
 40     for (int i=1;i<N+1;i++)
 41     {
 42         tree[i] = new node;
 43         tree[i]->data = i;
 44         tree[i]->left = nullptr;
 45         tree[i]->right = nullptr;
 46         tree[i]->flag=0;
 47     }
 48
 49     int head=num[0];
 50     stack<int> sta;
 51     int temp=0;
 52     for (int i=0;i<2*N-1;i++)
 53     {
 54         if (operation[i] == "Push")
 55             sta.push(num[i]);
 56         else
 57         {
 58             temp = sta.top();
 59             sta.pop();
 60         }
 61
 62         if (operation[i] == "Push" && operation[i+1] == "Push" )
 63         {
 64             tree[num[i]]->left = tree[num[i+1]];
 65         }
 66         else if (operation[i] == "Push" && operation[i+1] == "Pop" )
 67         {
 68             tree[num[i]]->left = nullptr;
 69         }
 70         else if (operation[i] == "Pop" && operation[i+1] == "Push" )
 71         {
 72             tree[temp]->right = tree[num[i+1]];
 73         }
 74         else //pop pop
 75             tree[temp]->right = nullptr;
 76     }
 77
 78     //开始后序输出
 79     stack<node*> out;
 80     node *T=tree[head];
 81
 82     while (T || !out.empty())
 83     {
 84         while (T)
 85         {
 86             out.push(T);
 87             T = T->left;
 88         }
 89
 90         if (!out.empty())
 91         {
 92             T = out.top();
 93
 94             if (T->flag)
 95             {
 96                 cout << T->data << ‘ ‘;
 97                 out.pop();
 98                 T=out.top();
 99             }
100             else
101             {
102                 T->flag = 1;
103                 T=T->right;
104             }
105         }
106     }
107
108     return 0;
109 }

 
时间: 2024-08-06 03:45:46

数据结构(陈越) 作业题 第三周的相关文章

数据结构(陈越) 作业题 第一周

1-1 最大子列和问题 20pts 时间限制 10000 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= K.“最大子列和”则被定义为所有连续子列元素的和中最大者.例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20.现要

20172328《程序设计与数据结构》第三周学习总结

20172328李馨雨<程序设计与数据结构>第三周学习总结 教材学习内容总结 1.学习使用new运算符建立对象(即实例化),了解null空引用.具体体悟 :类和对象的关系. 2.对象引用变量的声明和初始化.用"."来引用方法,并且需要保留(). 3.了解String类的一些基本方法和标准类库java API. 4.除了在java.lang中的变量无需import声明,其他都需要import声明(简化类的多次引用). 5.了解和使用Random类和Math类. 6.理解格式化

20172310 2017-2018《程序设计与数据结构》(下)第三周学习总结

20172310 2017-2018<程序设计与数据结构>(下)第三周学习总结 教材学习内容总结 第五章 队列 队列:队列是一种线性集合,其元素从一端加入,从另一端删除,队列中的元素是按先进先出的方式处理的(FIFO).一个队列一端为前端(front,head), 一端为末端(rear,tail). 队列ADT所定义的操作 Java API中的队列 1.Java集合API提供了java.util.Stack类,它实现了栈集合.但它并没有提供队列类,而是提供了一个Queue接口, 由多个类(包括

20172302 《程序设计与数据结构》第三周学习总结

学号20172302 2017-2018-2 <程序设计与数据结构>第3周学习总结 教材学习内容总结 1.对对象创建和对象引用变量的声明及初始化有了了解,再就是了解到别名这一概念,还知道了Java的自动执行垃圾回收的操作. 2.第二节了解了String类的具体的提供的一些方法,从后面的包的概念中了解到String类所归属的包为java.lang,由于其是最基本的包,内嵌于程序中,可以直接使用. 3.在包的这一节认识了几种常见常用的包,以及包中的类在使用的时候用使用import声明. 4.然后四

20172327 2017-2018-2 《程序设计与数据结构》第三周学习总结

20172327 2017-2018-2 <程序设计与数据结构>第三周学习总结 教材学习内容总结 讨论对象的创建和使用对象引用变量. 探索String类提供的服务. 描述如何组织成Java标准类库包. 探索随机和数学课提供的服务. 讨论如何使用NumberFormat和DecimalFormat类格式输出. 介绍枚举类型. 教材学习中的问题和解决问题 暂无 代码学习中的问题和解决过程 问题1:在做项目pp0301时,出现了下面这中情况 问题1解决方案:通过仔细的分析,我发现代码是对的,主要是数

20172325 2017-2018-2 《程序设计与数据结构》第三周学习总结

学号 2016-2017-2 <Java程序设计>第三周学习总结 教材学习内容总结 1.对对象创建和对象引用变量的声明及初始化有了了解,加深了对对象和变量的了解: 2.学习了string类的服务以及string类所归属的包: 3.明白了包的概念,以及各种类有其所归属的包还有包的常见类型: 4.学会了两种类的格式输出: 5.学习了枚举型和序数值. 教材学习中的问题和解决过程 问题1:对于浮点型和整数型的使用分不太清,导致在学习第三章的时候做练习时屡次出错,而且有时候错的简直一头雾水. 问题1解决

20172313 2018-2019-1 《程序设计与数据结构》第三周学习总结

20172313 2018-2019-1 <程序设计与数据结构>第三周学习总结 教材学习内容总结 概述 队列是一种线性集合,其元素从一端加入,从另一端删除:队列的元素是按FIFO方式处理的.第一个进入的元素,也就是第一个退出的元素. 队列有队头(front)和队尾(rear),数据从队尾进入队列,从队头出队列,队头(front)指向队列的第一个数据,队尾(rear)指向队列中的最后一个数据. JavaAPI中的队列 Java集合API提供了java.util.Stack类,它实现了栈集合.但它

2018-2019-20172329 《Java软件结构与数据结构》第三周学习总结

2018-2019-20172329 <Java软件结构与数据结构>第三周学习总结 教材学习内容总结 <Java软件结构与数据结构>第五章-队列 一.概述 1.队列是什么? 队列是种线性集合,其元素从一端加入,从另一端删除:注:队列是按照先进先出的方式处理的.从队列中删除元素的次序,与放置元素的次序是一样的. 2.队列的构成 (1)方法: 操作 描述 enqueue 向队列末端添加一个元素 dequeue 从队列前段删除一个元素 first 考察队列前端的那个元素 isempty

20172332 2017-2018-2 《程序设计与数据结构》第三周学习总结

20172332 2017-2018-2 <程序设计与数据结构>第三周学习总结 教材学习内容总结 第五章 队列 1.队列是一种线性集合,元素从一段加入从另一端删除(先进先出). 2.队尾(tail),队首(head),队列前端(front),队列末端(rear). 3.使用队列的一些实例:凯撒密码,售票口模拟. 4.分别用链表和数组实现队列. 5.双端队列,允许从队列的两端添加.删除和查看元素. 6.环形数组实现队列. 教材学习中的问题和解决过程 问题1:为什么用数组实现队列时,环形数组较好?