首页 > 其他 > 详细

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

时间:2016-02-16 23:29:47      阅读:945      评论:0      收藏:0      [点我收藏+]

02-1. Reversing Linked List

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard
作者
CHEN, Yue

Given a constant K and a singly linked list L, you are supposed to reverse the links of every K elements on L. For example, given L being 1→2→3→4→5→6, if K = 3, then you must output 3→2→1→6→5→4; if K = 4, you must output 4→3→2→1→5→6.

Input Specification:

Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (<= 105) which is the total number of nodes, and a positive K (<=N) which is the length of the sublist to be reversed. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.

Then N lines follow, each describes a node in the format:

Address Data Next

where Address is the position of the node, Data is an integer, and Next is the position of the next node.

Output Specification:

For each case, output the resulting ordered linked list. Each node occupies a line, and is printed in the same format as in the input.

Sample Input:
00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218
Sample Output:
00000 4 33218
33218 3 12309
12309 2 00100
00100 1 99999
99999 5 68237
68237 6 -1

此题的关键是如何表示这一个个结点。由于结点的地址和next都是一个具体的5位数,因此不能用链表这种“抽象的”方法来表示“具体的地址”。所以我们需要模拟实际的内存,办法就是用一个数组,数组下标为当前结点的地址,而数组的值就是该结点的next指针的地址。有了这种表示方法之后,后面就容易下手了。从输入中记录头结点的地址,然后一个个结点的next信息放入前面说的数组中,放好之后,实际上就构建好了输入的链表。
下一步是链表反转,按照陈姥姥的说法,最直观的做法是从头结点开始,把下一个结点的next设为上一个结点的地址,全部设置好之后再从头结点开始遍历输出。
而我的做法是用stl的vector,从头结点开始一个一个压入vector中,然后每K个元素进行逆序输出。
姥姥的习题课里说我的做法应该是超时的,而我确实是超了,但是!!!我后来改用了姥姥说的方法,还是超时!!!后来结果表明,超时的原因是我用了C++的cin和cout,改成scanf和printf后就好了。同时在我自己的vector做法里改成scanf和printf后也过了,(⊙﹏⊙)b....
这个题目有几个坑需要注意:
1.K是否能整除N关系到最后一段的输出
2.输入会有多余节点...这个坑我表示实在太大了...后来看了别人的文章才发现会有这个问题。多余节点就是不在链表里的结点,如果不去除,输出肯定不对
3.有一个test case的N很大,这时就要用C的scanf和printf才能不超时。

 1 #include<iostream>
 2 #include<iomanip>
 3 #include<vector>
 4 using namespace std;
 5 
 6 struct node{
 7     int data;
 8     int addr;
 9 };
10 
11 int main()
12 {    
13     int N=100000;
14 
15     int *data = new int [N];
16     int *next = new int [N];
17 
18     int begin_address=0;
19     int Nnodes=1;
20     int K=1;
21 
22     cin >> begin_address;
23     cin >> Nnodes;
24     cin >> K;
25     int *out = new int [K];
26 
27     int address_in,data_in,next_in;
28     node temp_node;
29     for (int i=0;i<Nnodes;i++)
30     {
31         scanf("%d",&address_in);
32         scanf("%d",&data[address_in]);
33         scanf("%d",&next[address_in]);
34     }
35 
36     vector<node> vec1;
37     while (begin_address != -1)
38     {
39         temp_node.data=data[begin_address];
40         temp_node.addr=begin_address;
41         vec1.push_back(temp_node);
42         begin_address = next[begin_address];
43     }
44     
45     //开始反遍历**********************************
46     Nnodes=vec1.size();
47     int segments=Nnodes/K;//分成了这么多段
48     int last=Nnodes%K;//最后一段有几个元素,如果=0,说明刚好分完。否则最后一段不用改
49     for (int i=0;i<segments;i++)
50     {
51         for (int j=0;j<K;j++)
52             if (j!=K-1)
53                 printf("%05d %d %05d\n", vec1[K*(i+1)-1-j].addr, vec1[K*(i+1)-1-j].data, vec1[K*(i+1)-1-j-1].addr);
54             else
55                 if (i==segments-1)//最后一段,分情况了
56                 {
57                     if (last)
58                     {
59                         printf("%05d %d %05d\n", vec1[K*(i+1)-1-j].addr, vec1[K*(i+1)-1-j].data, vec1[K*(i+1)].addr);
60                         for (int i=K*segments;i<Nnodes;i++)
61                         {
62                             if (i==Nnodes-1)
63                                 cout << setw(5) << setfill(0) << vec1[i].addr <<   << vec1[i].data <<   << -1 << endl;
64                             else
65                                 printf("%05d %d %05d\n",vec1[i].addr, vec1[i].data,  vec1[i+1].addr);
66                         }
67                     }
68                     else
69                     {
70                         cout << setw(5) << setfill(0) << vec1[K*(i+1)-1-j].addr <<   << vec1[K*(i+1)-1-j].data <<   << -1 << endl;
71                     }
72                 }
73                 else
74                     cout << setw(5) << setfill(0) << vec1[K*(i+1)-1-j].addr <<   << vec1[K*(i+1)-1-j].data <<   << setw(5) << setfill(0) << vec1[K*(i+2)-1].addr << endl;
75     }    
76 
77     return 0;
78 }

 


02-2. 一元多项式求导


时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard

设计函数求一元多项式的导数。

输入格式:以指数递降方式输入多项式非零项系数和指数(绝对值均为不超过1000的整数)。数字间以空格分隔。

输出格式:以与输入相同的格式输出导数多项式非零项的系数和指数。数字间以空格分隔,但结尾不能有多余空格。注意“零多项式”的指数和系数都是0,但是表示为“0 0”。

输入样例:
3 4 -5 2 6 1 -2 0
输出样例:
12 3 -10 1 6 0
本题比较简单,直接输入一项,接着输出一项就可以。但是,本题我有个地方没考虑到。就是如果输入3 0,那么应该输出0 0.
还有个地方值得学习,就是输出的最后不能带有空格。一开始我是想判断什么时候是最后一组输入,发现这样做太麻烦,而且容易出错。最好的办法是先弄第一组输入,输出a_b,后面每组输出_a_b,而不是每一组都输出a_b_
 1 #include<iostream>
 2 #include<stdio.h>
 3 #include<vector>
 4 using namespace std;
 5 
 6 int main()
 7 {
 8     int coeff,expon;
 9     scanf("%d %d",&coeff, &expon);
10 
11     if (expon == 0)
12         printf("%d %d",0,0);
13     else
14         printf("%d %d",coeff*expon,expon-1);
15 
16     while (cin >> coeff >> expon)
17     {
18         if (expon)
19             printf(" %d %d",coeff*expon,expon-1);
20     }
21 
22     return 0;
23 }

02-3. 求前缀表达式的值

时间限制
400 ms
内存限制
65536 kB
代码长度限制
8000 B
判题程序
Standard

算术表达式有前缀表示法、中缀表示法和后缀表示法等形式。前缀表达式指二元运算符位于两个运算数之前,例如2+3*(7-4)+8/4的前缀表达式是:+ + 2 * 3 - 7 4 / 8 4。请设计程序计算前缀表达式的结果值。

输入格式说明:

输入在一行内给出不超过30个字符的前缀表达式,只包含+、-、*、\以及运算数,不同对象(运算数、运算符号)之间以空格分隔。

输出格式说明:

输出前缀表达式的运算结果,精确到小数点后1位,或错误信息“ERROR”。

样例输入与输出:

序号 输入 输出
1
+ + 2 * 3 - 7 4 / 8 4
13.0
2
/ -25 + * - 2 3 4 / 8 4
12.5
3
/ 5 + * - 2 3 4 / 8 2
ERROR
4
+10.23
10.2
 
本题我用的方法是堆栈stack。首先判断第一个输入的元素是什么,如果是数字,则判断是否还有下一个输入,如果有,则出错,输出ERROR,如果没有,则输出前一个数字,程序结束。
如果第一个输入是操作符,则压到堆栈里。当输入数字时,判断栈顶是什么。如果是操作符,再将刚才的数字压入堆栈。如果是数字,则判断再下一个元素是什么,如果是操作符,则可以进行运算了,如果是数字,则ERROR。这一步循环进行到栈顶是操作符或者栈为空。输入完之后,判断堆栈剩下什么。如果是空,或者栈顶是操作符,则ERROR。如果不止一个元素,也ERROR。其余情况输出剩下的那一个数字。
关于这题运算数和运算符的表示,我用了一个结构体,包含了一个string域和double域。输入的时候都输入到string,如果判断到是数字,则用atof把string转换成double型。

  1 #include<iostream>
  2 #include<iomanip>
  3 #include<stack>
  4 #include<string>
  5 using namespace std;
  6 
  7 struct term
  8 {
  9     int flag; //0时为运算符,1时为运算数
 10     string _operator;
 11     double operand;
 12 };
 13 
 14 int main()
 15 {
 16     term in,temp_operand;
 17     stack<term> sta;
 18 
 19     string in_temp;
 20     cin >> in_temp;
 21     
 22     if ( !(in_temp == "+" || in_temp == "-" || in_temp == "*" ||in_temp == "/" ) )//第一个输入是数字
 23     {
 24         in.flag=1;in.operand=atof(in_temp.c_str());
 25         sta.push(in);
 26         if (cin >> in_temp)
 27         {cout << "ERROR" << endl;return 0;}
 28         else
 29         {cout << fixed << setprecision(1) << sta.top().operand << endl;return 0;}
 30     }
 31     else
 32     {
 33         in.flag=0;in._operator=in_temp;
 34         sta.push(in);
 35     }
 36 
 37     while (cin >> in_temp)
 38     {
 39         if ( !(in_temp == "+" || in_temp == "-" || in_temp == "*" ||in_temp == "/" ) )
 40         {
 41             in.flag=1;in.operand=atof(in_temp.c_str());
 42         }
 43         else
 44         {
 45             in.flag=0;in._operator=in_temp;
 46         }
 47 
 48         if ( in.flag ) //数字,要判断top是什么
 49         {
 50             if (sta.empty())
 51                 {cout << "ERROR" << endl;return 0;}
 52             else
 53                 if ( !sta.top().flag ) //是运算符
 54                 {
 55                     sta.push(in);
 56                 }
 57                 else
 58                 {
 59                     while (!sta.empty() && sta.top().flag) //输入数字,且top也是数字
 60                     {
 61                         temp_operand = sta.top();
 62                         sta.pop();
 63                         if (sta.empty())
 64                             {cout << "ERROR" << endl;return 0;}
 65                         else
 66                             if ( !sta.top().flag )
 67                             {
 68                                 if (sta.top()._operator == "+")
 69                                     temp_operand.operand += in.operand;
 70                                 else if (sta.top()._operator == "-")
 71                                     temp_operand.operand -= in.operand;
 72                                 else if (sta.top()._operator == "*")
 73                                     temp_operand.operand *= in.operand;
 74                                 else 
 75                                     if (in.operand == 0)
 76                                         {cout << "ERROR" << endl;return 0;}
 77                                     else
 78                                         temp_operand.operand /= in.operand;
 79                                 sta.pop();
 80                                 in = temp_operand;
 81                             }
 82                             else
 83                                 {cout << "ERROR" << endl;return 0;}
 84 
 85                     }
 86                     sta.push(in);
 87                 }
 88         }
 89         else //符号,直接push进去
 90             sta.push(in);
 91     }
 92     
 93     if (sta.empty())
 94         {cout << "ERROR" << endl;return 0;}
 95     else
 96         if (!sta.top().flag)
 97             cout << "ERROR" << endl;
 98         else
 99             if (sta.size()==1)
100                 cout << fixed << setprecision(1) << sta.top().operand << endl;
101             else
102                 cout << "ERROR" << endl;
103         
104     return 0;
105 }

 

 

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

原文:http://www.cnblogs.com/xian-ye/p/5193968.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!