/********************************************************************************* 72. (NOI'95.1_2) 在一个园形操场的四周摆放 N 堆石子(N≤100), 现要将石子 有次序地合并成一堆。规定每次只能选相邻的两堆合并成新的一堆,并将新的一堆 的石子数,记为该次合并的得分。 编一程序,由文件读入堆数 N 及每堆的石子数(≤20), ① 选择一种合并石子的方案, 使得做N-1次合并, 得分的总和最小; ② 选择一种合并石子的方案, 使得做N-1次合并, 得分的总和最大. 例如, 图 2-1 所示的4堆石子,每堆的石子数(从最上面的一堆数起, 顺时针数) 依次为4 5 9 4. 则 3 次合并得分总和最小的方案为图2-2,得分总和最大的方案 为图 2-3. (加图) 输入数据: 文件名由键盘输入,该文件内容为; 第一行为石子堆数 N; 第二行为每堆的石子数, 每两个数之间用一个空格符分隔 输出数据: 输出文件名为 OUTPUT.TXT 第 1 至 N-1 行为得分最小的合并过程. 每行包含两个数, 表示应该合并的两 堆石子的数目, 小数在前, 大数在后, 第 N 行为合并成一堆后的最小得分总和; 第 N+1 行为空行, 第 N+2 至 2N+1 行为得分最大合并过程(格式同前). 第 2N+2 行为最大得分总和. **********************************************************************************/ #include <stdio.h> #include <malloc.h> typedef struct tagTreeNode { int data; tagTreeNode *left; tagTreeNode *right; } TreeNode; typedef struct tagLinkNode { TreeNode *pTreeNode; tagLinkNode *pNext; } LinkNode; LinkNode *head = NULL; LinkNode *tail = NULL; TreeNode *root = NULL; //创建一个链表,保存数列 void CreateLink(FILE *fp, int n) { int i; int data; TreeNode *tempTreeNode; LinkNode *tempLinkNode; for(i=0; i<n; i++) { fscanf(fp,"%d",&data); tempTreeNode = (TreeNode*)malloc(sizeof(TreeNode)); tempTreeNode->data = data; tempTreeNode->left = NULL; tempTreeNode->right = NULL; tempLinkNode = (LinkNode*)malloc(sizeof(LinkNode)); tempLinkNode->pTreeNode = tempTreeNode; tempLinkNode->pNext = NULL; if(!head) { head = tail = tempLinkNode; tail->pNext = head;//尾节点指向头节点 } else { tail->pNext = tempLinkNode; tail = tail->pNext; tail->pNext = head;//尾节点指向头节点 } } } //插入元素 LinkNode* InsertAfter(LinkNode *pLinkNode,int data) { TreeNode *tempTreeNode; LinkNode *tempLinkNode = NULL; if(pLinkNode) { tempTreeNode = (TreeNode*)malloc(sizeof(TreeNode)); tempTreeNode->data = data; tempTreeNode->left = NULL; tempTreeNode->right = NULL; tempLinkNode = (LinkNode*)malloc(sizeof(LinkNode)); tempLinkNode->pTreeNode = tempTreeNode; tempLinkNode->pNext = NULL; tempLinkNode->pNext = pLinkNode->pNext; pLinkNode->pNext = tempLinkNode; if(pLinkNode == tail) tail = tempLinkNode; } return tempLinkNode; } //删除元素 void DeleteLinkNode(LinkNode *pLinkNode) { LinkNode *p,*q; if(pLinkNode == head) { if(head == tail) { head = tail = NULL; } else { head = head->pNext; tail->pNext = head; } free(pLinkNode); } else { p = tail; q = head; while(q != tail) { if(q == pLinkNode) { p->pNext = q->pNext; free(pLinkNode); break; } p = q; q = q->pNext; } if(q == tail) { tail = p; p->pNext = q->pNext; free(pLinkNode); } } } //计算 int CalcMin() { int sum = 0; int min_sum; LinkNode *p,*q,*min,*pnew; while(head != tail) { p = tail; q = head; min = p; min_sum = min->pTreeNode->data + min->pNext->pTreeNode->data; do { if(q->pTreeNode->data + p->pTreeNode->data < min_sum) { min = p; min_sum = min->pTreeNode->data + min->pNext->pTreeNode->data; } p = q; q = q->pNext; }while(q != head); sum += min_sum; pnew = InsertAfter(min->pNext,min_sum); pnew->pTreeNode->left = min->pTreeNode; pnew->pTreeNode->right = min->pNext->pTreeNode; DeleteLinkNode(min->pNext); DeleteLinkNode(min); } root = head->pTreeNode; DeleteLinkNode(head); return sum; } int CalcMax() { int sum = 0; int max_sum; LinkNode *p,*q,*max,*pnew; while(head != tail) { p = tail; q = head; max = p; max_sum = max->pTreeNode->data + max->pNext->pTreeNode->data; do { if(q->pTreeNode->data + p->pTreeNode->data > max_sum) { max = p; max_sum = max->pTreeNode->data + max->pNext->pTreeNode->data; } p = q; q = q->pNext; }while(q != head); sum += max_sum; pnew = InsertAfter(max->pNext,max_sum); pnew->pTreeNode->left = max->pTreeNode; pnew->pTreeNode->right = max->pNext->pTreeNode; DeleteLinkNode(max->pNext); DeleteLinkNode(max); } root = head->pTreeNode; DeleteLinkNode(head); return sum; } //打印结果 void main() { int n; FILE *fp,*fpw; int rs; fp = fopen("input.txt","r"); if(!fp) { printf("fail to open the file input.txt!/n"); return; } fscanf(fp,"%d",&n); printf("石子堆数N: %d/n", n); // fpw = fopen("output.txt","w"); CreateLink(fp,n); rs = CalcMin(); printf("min = %d/n",rs); fseek(fp,0,SEEK_SET); fscanf(fp,"%d",&n); CreateLink(fp,n); rs = CalcMax(); printf("max = %d/n",rs); fclose(fp); }
练习72
最新推荐文章于 2023-05-08 22:26:15 发布