NEUQ-acm预备队训练Week1-模拟与高精度

1.模拟乒乓球11赛制与21赛制

习题 7-1

NEUQ-acm预备队训练Week1-模拟与高精度_第1张图片
想法:使用队列,定义两个参数i(表示W的个数)、j(表示L的个数),谁先到11(21)就输出或队列为空输出当前比分。

#include 
using namespace std;
int numw, numl, num;
 queue<char> q1, q2;
void print(){
    int i=0, j=0;//i记录W的个数,j记录L的个数
    //int n=0; //记录输出前W的个数 
    if(q1.empty()) cout << "0:0" << endl;
    while(!q1.empty()){
        if(q1.front()=='L') j++;
        if(q1.front()=='W') i++;
        q1.pop();
        if((i>=11&& i-j>=2) || (j>=11 && j-i>=2) || q1.empty()){
            printf("%d:%d\n",i,j);
            if(q1.empty() && abs(i-j)>=2 
               && ((i>=11&& i-j>=2) || (j>=11 && j-i>=2))) 
               cout << "0:0" << endl;
            i=0; j=0;
        }
    }
    cout << endl;
    int ii=0, jj=0;//i记录W的个数,j记录L的个数
    if(q2.empty()) cout << "0:0" << endl;
    while(!q2.empty()){
        if(q2.front()=='L') jj++;
        if(q2.front()=='W') ii++;
        q2.pop();
        if((ii>=21&& ii-jj>=2) || (jj>=21 && jj-ii>=2) || q2.empty()){
            printf("%d:%d\n",ii,jj);
            if(q2.empty() && abs(ii-jj)>=2
              && ((ii>=21&& ii-jj>=2) || (jj>=21 && jj-ii>=2)))
                cout << "0:0" << endl;
            ii=0; jj=0;
        }
    }
}
int main(){
    char x;
    while(cin >> x){
        switch(x){
            case 'W': num++; numw++; q1.push(x); q2.push(x); break; 
            case 'E': print(); return 0;
            case 'L': num++; numl++; q1.push(x); q2.push(x); break;
        }
    }
    
}

迷糊瞬间~
1.先开始想得是打满11(21)局
2.题目有坑,需要比分大于等于2才能分出胜负
3.上一局若分出胜负,且已经列表空了,需要输出0:0

2、什么是高精度数

定义:

在一般的科学计算中,会经常算到小数点后几百位或者更多,甚至几千亿几百亿的大数字。一般这类数字我们统称为高精度数。 对于一个很大的数字N >= 10^ 100,那么我们该如何存储到计算机中呢?
即将这个数字拆开,拆成一位一位的或者是四位四位的存储到一个数组中,用一个数组去表示一个数字。这样这个数字就被称谓是高精度数。 对于高精度数,也应能像平常数一样做加减乘除的运算。

基本思路:

​ 1、以字符串的方式读入数字并保存在字符数组中。

​ 2、计算字符数组中总字符数,即高精度数的位数,记为n。

​ 3、定义整型数组存每一位上的数,存储时需要倒序存储,也即最低位在前,最高在后,另0号位置存位数。例如数字1235在数组中存储顺序为:45321

习题 7-2

NEUQ-acm预备队训练Week1-模拟与高精度_第2张图片

#include 
using namespace std;
int a[105],b[105];
int main(){
    string c1,c2;
    cin >> c1;
    cin >> c2;
    a[0]=c1.length();
    b[0]=c2.length();
    for(int i=a[0]; i > 0; i--){
        a[a[0]+1-i]=c1[i-1]-'0';
    }
    for(int i=b[0]; i > 0; i--){
        b[b[0]+1-i]=c2[i-1]-'0';
    }
    int m=max(a[0],b[0]);
    for(int i = 1; i <= m; i++){
        a[i]+=b[i];
        a[i+1]+=a[i]/10;
        a[i]%=10;
    }
    if(a[m+1]!=0){
        m++;
        a[0]=m;}
    for(int i = m; i >0; i--)  cout << a[i];
    //for(int i = a[0]; i >0; i--)  cout << a[i];
}

迷糊瞬间~ 注释行a[0]不一定就是max(a[0],b[0])

习题 7-3

NEUQ-acm预备队训练Week1-模拟与高精度_第3张图片
用到求和公式S=n(n+1)/2;
由此需要有高精度的乘积,加法,以及除以2之后的输出

#include 
using namespace std;
int a[105], b[105], c[100005];
void get(string n){
     a[0]=n.length();
    for(int i=a[0]; i > 0; i--){
        a[a[0]+1-i]=n[i-1]-'0';
    }
    b[0]=1; b[1]=1;
}
void print(){
    for(int i = c[0]; i>0; i--){
        if(c[c[0]]!=1 || i<c[0])
        cout << c[i]/2;
        c[i-1]+=10*(c[i]%2);
    }
}
void add1(int a[],int b[]){
    int m=max(a[0],b[0]);
    b[0]=m;
    for(int i = 1; i <= m; i++){
        b[i]+=a[i];
        b[i+1]+=b[i]/10;
        b[i]%=10;
    }
    if(b[m+1]!=0) c[0]++;
}
void multi(){
	for(int i=1;i<=a[0];++i){
		for(int j=1;j<=b[0];++j){
			c[i+j-1]+=a[i]*b[j];
		}
	}
    c[0]=a[0]+b[0];
	for(int i=1;i<c[0];++i){
		if(c[i]>=10){
			c[i+1]+=c[i]/10;
			c[i]%=10;
		}
	} 
	while(c[c[0]]==0&&c[0]>0){
		c[0]--;
	} 
}
int main(){
    string n;
    cin >> n;
    get(n);
    add1(a,b);
    multi();
    print();
}

这道题写了4天,先开始用 n*(n)+n,再除以2算一直有一个点没通过,后来用n*(n+1)再除以2就通过了,两次使用的代码都相同,只是参数及函数调用次序不同,不明白为什么了……

你可能感兴趣的:(ACM预备队训练,c++,算法,开发语言)