好的,寶寶又來寫東西啦~這次的題目是一道多項式計算題:輸入兩個多項式,輸出他們的乘積與和,格式大概是這樣:[PAT] 02-線性結構1 一元多項式的乘法與加法運算
設計函數分別求兩個一元多項式的乘積與和。
輸入格式:
輸入分2行,每行分別先給出多項式非零項的個數,再以指數遞降方式輸入一個多項式非零項系數和指數(絕對值均為不超過1000的整數)。數字間以空格分隔。
輸出格式:
輸出分2行,分別以指數遞降方式輸出乘積多項式以及和多項式非零項的系數和指數。數字間以空格分隔,但結尾不能有多余空格。零多項式應輸出
0 0
。輸入樣例:
4 3 4 -5 2 6 1 -2 0 3 5 20 -7 4 3 1
輸出樣例:
15 24 -25 22 30 21 -10 20 -21 8 35 6 -33 5 14 4 -15 3 18 2 -6 1 5 20 -4 4 -5 2 9 1 -2 0
- 時間限制:200ms
- 內存限制:64MB
- 代碼長度限制:16kB
- 判題程序:系統默認
- 作者:DS課程組
- 單位:浙江大學
[
15 24] [-25 22] [30 21] [-10 20]...
每個中括號前面的是系數,后面的是指數,排序是指數從高到低.
這題難度本身不大,做出來很容易.但是要追求速度和更少內存消耗的話還是需要考慮用什么方式去儲存和處理這些數據,下面給出我個人的一個方法:求乘積用雙向鏈表,求和用動態數組.另外,我的代碼比較長,因為我采用的是"空間換時間"的總體方向,所以消耗較多儲存空間,好處是不用遞歸函數,那個是計算機最不擅長的事情.
#include <stdio.h> #include <stdlib.h> typedef struct { int cofe; int expo; } NODE; typedef struct _List { int cofe; int expo; struct _List * _next; struct _List * _back; } List;
構造一個NODE型的struct.存放原始每一項的系數(cofe)和指數(expo),再構造一個List型的struct,這是一個可以增長的鏈表,在原始數據里面不斷抽取數據按指數大小進行比較排序,若指數比當前指的小就向后(左)移動一位,比當前大就向后(右)移動一位如果已經指到頭則新建一個節點再寫入,這其中的判斷邏輯還包括系數相乘后寫入系數區,排序結束后的雙向鏈表就可以直接輸出了.
1 int main(void) //全局初始化,包括建立各種變量以及讀入原始數據 2 { 3 int PolyOneCount,PolyTwoCount,i,k,cofe_temp,expo_temp,flag=1,Once=1,NotZeroCount=0; 4 NODE* PolyOne=NULL; 5 NODE* PolyTwo=NULL; 6 List* PL=NULL; 7 NODE* PolySum=NULL; 8 List* PTemp; 9 NODE* P1=NULL; 10 NODE* P2=NULL; 11 scanf("%d",&PolyOneCount); 12 P1=PolyOne=(NODE*)malloc(PolyOneCount*sizeof(NODE)); 13 for ( i=0; i<PolyOneCount; i++ ) 14 { 15 scanf("%d",&((PolyOne+i)->cofe)); 16 scanf("%d",&((PolyOne+i)->expo)); 17 } 18 scanf("%d",&PolyTwoCount); 19 P2=PolyTwo=(NODE*)malloc(PolyTwoCount*sizeof(NODE)); 20 for ( i=0; i<PolyTwoCount; i++ ) 21 { 22 scanf("%d",&((PolyTwo+i)->cofe)); 23 scanf("%d",&((PolyTwo+i)->expo)); 24 } 25 List* PC=(List*)calloc(1,sizeof(List)); //PC是游走的指針,相當於一個爪子,把元素送到它需要去的地方
全局初始化,包括建立各種變量以及讀入原始數據.
1 for (i=0; i<PolyOneCount; i++) 2 for (k=0; k<PolyTwoCount; k++) 3 { 4 cofe_temp=((PolyOne+i)->cofe)*((PolyTwo+k)->cofe); 5 expo_temp=((PolyOne+i)->expo)+((PolyTwo+k)->expo); 6 while (1) 7 { 8 if (Once) 9 { 10 PC->cofe = cofe_temp; 11 PC->expo = expo_temp; 12 PL=PC; 13 Once=0; 14 break; 15 } 16 17 18 if (expo_temp > PC->expo) //元素需要后移 19 { 20 if (PC->_next) //鏈表存在下一節點 21 { 22 flag=1; 23 if (expo_temp > (PC->_next)->expo) //尚未到位 24 PC=PC->_next; 25 else if (expo_temp < (PC->_next)->expo) //已到位 26 { 27 PTemp = (List*)calloc(1,sizeof(List)); 28 PTemp->_next = (PC->_next); 29 (PC->_next)->_back = PTemp; 30 PC->_next = PTemp; 31 PTemp->_back = PC; 32 PC=PC->_next; 33 PC->cofe = cofe_temp; 34 PC->expo = expo_temp; 35 break; 36 } 37 else if (expo_temp == (PC->_next)->expo) //元素與下一個相等 38 { 39 PC=PC->_next; 40 (PC->cofe)+=cofe_temp; 41 flag=0; 42 break; 43 } 44 } 45 46 else //雙向鏈表無下一節點. 47 { 48 PTemp = (List*)calloc(1,sizeof(List)); 49 PTemp->_back = PC; 50 PL=PTemp; 51 PC->_next = PTemp; 52 PC=PC->_next; 53 PC->cofe = cofe_temp; 54 PC->expo = expo_temp; 55 56 break; 57 } 58 } 59 60 else if (expo_temp < PC->expo) //元素需要前移 61 { 62 if (PC->_back) //存在前驅節點 63 { 64 flag=1; 65 if (expo_temp < (PC->_back)->expo) //未到位 66 PC=PC->_back; 67 else if (expo_temp > (PC->_back)->expo) //已到位 68 { 69 PTemp = (List*)calloc(1,sizeof(List)); 70 PTemp->_back = (PC->_back); 71 (PC->_back)->_next = PTemp; 72 PC->_back = PTemp; 73 PTemp->_next = PC; 74 PC=PC->_back; 75 PC->cofe = cofe_temp; 76 PC->expo = expo_temp; 77 break; 78 } 79 else if (expo_temp == (PC->_back)->expo) 80 { 81 PC=PC->_back; 82 (PC->cofe)+=cofe_temp; 83 flag=0; 84 } 85 } 86 else //不存在前驅節點 87 { 88 PTemp = (List*)calloc(1,sizeof(List)); 89 PTemp->_next = PC; 90 // PH=PTemp; 91 PC->_back = PTemp; 92 PC=PC->_back; 93 PC->cofe = cofe_temp; 94 PC->expo = expo_temp; 95 break; 96 97 } 98 } 99 100 else 101 { 102 if (flag) (PC->cofe)+=cofe_temp; 103 break; 104 } 105 } 106 }
107 PC=PL;
以上是乘積計算代碼,Once是一個標志,用來創建第一個節點.兩個for循環用來遍歷所有的乘積組合,當然也是這個程序中時間復雜度最高的一段代碼,達到了O(N2).
1 for (;PC;PC=PC->_back) 2 { 3 if (PC->_back != NULL) 4 { 5 if (PC->cofe) 6 { 7 printf("%d %d ",PC->cofe,PC->expo); 8 NotZeroCount++; 9 } 10 else continue; 11 } 12 else
13 { 14 printf("%d %d\n",PC->cofe,PC->expo); 15 NotZeroCount++; 16 } 17 } 18 if (!NotZeroCount) printf("0 0\n"); 19 NotZeroCount=0;
輸出語句,中間有個if是因為題目要求最后一個不帶空格;最后一個判斷是看看是否是零多項式,如果是就輸出"0 0"(題目要求)
1 int max = 0,Lowest = 0; 2 if ( PolyOne->expo >= PolyTwo->expo ) max = PolyOne->expo; 3 else max = PolyTwo->expo; 4 PolySum=(NODE*)calloc(max+1,sizeof(NODE)); 5 i=k=0; 6 for (i=0;i<PolyOneCount;i++) 7 { 8 (PolySum+((PolyOne+i)->expo))->cofe += (PolyOne+i)->cofe; 9 (PolySum+((PolyOne+i)->expo))->expo = (PolyOne+i)->expo; 10 } 11 for (i=0;i<PolyTwoCount;i++) 12 { 13 (PolySum+((PolyTwo+i)->expo))->cofe += (PolyTwo+i)->cofe; 14 (PolySum+((PolyTwo+i)->expo))->expo = (PolyTwo+i)->expo; 15
16 } 17 NotZeroCount=0; 18 for (i=0;i<=max;i++) 19 { 20 if( (PolySum+i)->cofe ) 21 { 22 NotZeroCount=1; 23 Lowest=i; 24 break; 25 } 26 } 27 if (!NotZeroCount) printf("0 0"); 28 else
29 for (k=max;k>=0;k--) 30 if ((PolySum+k)->cofe != 0) 31 { 32
33 if (k==Lowest) printf("%d %d",(PolySum+k)->cofe,(PolySum+k)->expo); 34 else printf("%d %d ",(PolySum+k)->cofe,(PolySum+k)->expo); 35
36 } 37 return 0; 38 }//這里沒有寫free,因為做題時追求速度就省略了這一步,但是大家應當養成"一個malloc一個free"的好習慣
這里是加法的處理,直接給一個NODE型數組,其大小取兩個多項式中最大指數加一為數組大小.畢竟相加的指數最大值不超過單個指數的最大值,於是數組的下標就是對應指數的存放地址啦.這里不需要考慮太多,直接連續把兩個多項式加到新建的數組上,加完以后用一個for檢查系數是不是全是0,如果不是,再用一個for從高指數往低指數輸出所有系數非0的一組數據,就此完成~
P.S 下方附PTA運行結果