菜鸟记录:c语言实现PAT甲级1002--Polynomials
开始前有必要说一下,这才第二题就碰到了烂尾题,以自己开始的思路交了n次,错了n词,最后才19分,后来看了一下大佬的c++代码(尽然没有c的代码),还好c和c++的差别不是特别大,仔细琢磨一遍后突然发现很多地方可以改进,整理思路在此尝试终于AC,这才第二题啊。。。。
This time, you are supposed to find A+B where A and B are two polynomials.
Input Specification:
Each input file contains one test case. Each case occupies 2 lines, and each line contains the information of a polynomial:
K N1 aN1 N2 aN2 ... NK aNK
where K is the number of nonzero terms in the polynomial, Ni and aNi (i=1,2,⋯,K) are the exponents and coefficients, respectively. It is given that 1≤K≤10,0≤NK<⋯<N2<N1≤1000.
Output Specification:
For each test case you should output the sum of A and B in one line, with the same format as the input. Notice that there must be NO extra space at the end of each line. Please be accurate to 1 decimal place.
Sample Input:
2 1 2.4 0 3.2
2 2 1.5 1 0.5
Sample Output:
3 2 1.5 1 2.9 0 3.2
题目分析:
两行数据A和B,每一行的第一个数字 K 是它的非零项(即a不等于0),接下来的2*K个数字由K个数据N和K个数据a组成,N是指数(exponents),即下标,a是系数(coefficients),输入的例子中第一行,2是2个非零数,然后a1=2.4,a0=3.2,第二行,2个非零数,a2=1.5,a1=0.5。现在将A,B两行下标相等的数字相加,输出所有非零数个数、数值和其下标,即3个非零数,a2=1.5,a1=2.9(2.4+0.5),a0=3.2。输出结尾不得有多余空格。
个人想法:
错误想法(正确的在下面):开始笔者是想划分两个数组,分别存放下标N[]、存放数值a[],赋值时,即用a[N[i]]来将一个值存放在循环中N数组存储的下标位置,例如存入4.3,N[1]=6,a[N[1]]=a[6]=4.3,赋值A行全部结束后,用tmp赋值B行时,直接加上即·a[xx]+=tmp,最后遍历找非零项,记录个数,输出非零项就好了,下面是代码:
1 #include <stdio.h> 2 #define A 10001; 3 int K;//非0值 4 int N[1001];//存放下标N 5 double a[10001], b[10001]; 6 7 int main() 8 { 9 double tmp; 10 scanf("%d", &K); 11 for (int i = 0; i < K; i++) 12 { 13 scanf("%d%lf", &N[i], &tmp); 14 a[N[i]] = tmp; 15 }//第一行输入的数 16 scanf("%d", &K); 17 for (int i = 0; i < K; i++) 18 { 19 scanf("%d%lf", &N[i], &tmp); 20 a[N[i]] += tmp; 21 } 22 int p = 0; 23 if (a[0])p = 1; 24 for (int i = 0; i < 10001; i++) 25 { 26 if (a[i] && N[i] != 0) 27 ++p; 28 } 29 printf("%d", p); 30 for (int i = 10000; i >= 0; i--) 31 { 32 if (a[i] != 0) 33 printf(" %d %.1lf", i, a[i]); 34 } 35 printf("\n"); 36 return 0; 37 }
由于自己的这个想法只能拿到19分,这里就不贴出自己前面错误改进后的代码了。也请给位看官有兴趣的帮忙指正我的代码漏洞。
<----------接下来是满分代码------------>
其实代码总体思路是不变的,但是大佬的代码更加简洁、清楚,原先的下标数组N直接变成常量赋值,即a[N],整体过程也不再那么抽象,甚至用多个数组标记A、B输入数组和最后的输出数组。通过代码更容易看出:
1 #include <stdio.h> 2 #define A 10001; 3 4 int main() 5 { 6 double t;//数值 7 int count=0; 8 int K;//非0值 9 int N;//下标值 10 double a[1001], b[1001],c[1001];//两个输入值和最后输出数组 11 memset(a, 0.0, sizeof(a)); 12 memset(b, 0.0, sizeof(b)); 13 memset(c, 0.0, sizeof(c));//初始化,个人认为设为全局变量就行,不用初始化了 14 scanf("%d", &K); 15 for (; K > 0; K--) { 16 scanf("%d%lf",&N,&t); 17 a[N] = t; 18 } 19 scanf("%d", &K); 20 for (; K > 0; K--) { 21 scanf("%d%lf", &N, &t); 22 b[N] = t; 23 }//A、B的数值输入 24 for (int i=0; i<1001; i++) { 25 if (a[i] != 0 || b[i] != 0) {//遍历所有范围,如果输入数组存在非0项,则放入输出数组 26 c[i] = a[i] + b[i]; 27 if(c[i]!=0) 28 count++; 29 } 30 } 31 printf("%d", count);//输出非0项数的数目 32 for (int i =1000 ; i >=0; i--) { 33 if (c[i] != 0) 34 printf(" %d %.1lf", i, c[i]); 35 } 36 37 return 0; 38 }
满分通过。
总结:
由于一些测试点看不到,所有原先最后那没通过还是不清楚,看了几次也看不出来哪里有遗漏的地方,暂时也只能这样了,功夫不到家,差的太远。还有照例英语。