1. 题目
2. 分析
3. 代码
加了一些看起来冗杂的注释。。。(没错就是为了交报告
#include <iostream>
#include <malloc.h>
using namespace std;
typedef struct node{
int data;
struct node *pre;
struct node *next;
}Node;
void createList(Node *head){ // 创建一个双向链表
head->next = head;
head->pre = head;
Node *p, *q;
p = head;
// 直接预设1000位,题意所需位数n在1000以内
for(int i=0; i<1000; i++){
q = (Node*) malloc(sizeof(Node));
q->data = 0;
q->pre = p;
p->next = q;
q->next = head;
head->pre = q;
p = p->next;
}
}
void cal(Node *headnum, Node *headsum){
headnum->next->data = 3; //由于取的是PI/6,计算结果为1/2,则6/2=3
headsum->next->data = 3;
int a=0, b=0; // a存当前项的计算值,b存进位或余数
// 方法是计算出2000项的加和的值,之后按照题目所需的n值进行取相应位数
for(int i=1; i<=2000; i++){ // 对每一项(即每一个i值所对应的项)进行计算
Node *p, *q;
//先计算大数乘法,从低位即链表尾部开始计算
p = headnum->pre;
while(p != headnum){
a = p->data * (2*i-1) * (2*i-1) + b; // 存放当前位计算后的值,之后根据当前位的计算值计算进位b和p->data
p->data = a % 10; // 进位的部分,留在当前位上
b = a/10; // 进位的部分,存在b里面,之后在进位时参与计算(计算a)
p = p->pre; // 指针前移一位
}
b = 0;
//再计算大数除法,从高位开始计算
p = headnum->next;
while(p != headnum){
a = p->data + b*10; //除法借位b需要乘以10,加上当前p->data,成为当前需要计算的值
p->data = a/((2*i+1)*(2*i)*4); // 对于除法,商可以直接留在当前位上
b = a % ((2*i+1)*(2*i)*4); // 对于除法,余数需要在下一位进行借位,即成为b
p = p->next; //指针后移一位
}
b = 0;
//最后将每一项加入sum中,由于是由于是大数和大数的加法,从低位开始加起
p = headnum->pre; // p指向每一项的值(此时该项已经在之前计算出来了)
q = headsum->pre; // q指向之前已经计算好的sum值,准备与新计算出来的项num相加
while(p != headnum){
a = p->data + q->data + b; //存放当前位加上进位的值
q->data = a%10; //非进位部分,留在当前位上
b = a/10; //进位部分,存在b中
p = p->pre; //指针前移一位
q = q->pre; //指针前移一位
}
}
}
int main(int argc, char** argv) {
int n;
cin >> n;
Node *headnum, *headsum; // 两个链表,分别存放 当前计算的项num 和 加和sum
headnum = (Node*) malloc(sizeof(Node));
headsum = (Node*) malloc(sizeof(Node));
createList(headnum);
createList(headsum);
cal(headnum, headsum);
cout << "3.";
Node *p = headsum->next->next;
for(int i=0; i<n; i++){
cout << p->data;
p = p->next;
}
return 0;
}