【qscoj】伊苏比的梦幻之旅之魔方(枚举+公式+高精度)

来源:互联网 发布:it行业人才 编辑:程序博客网 时间:2024/04/29 16:56

描述
timg.jpg

刘老师很喜欢玩魔方。平均速度二阶20秒,三阶1分钟,四阶3分30秒,五阶8分钟。一个N阶魔方由N*N*N个小方块构成,而这些小方块又分为中心块、棱块和角块三部分,中心块为只有1面朝外的小方块,棱块为2面朝外的小方块,角块为3面朝外的小方块。请你帮刘老师统计,一个N阶魔方,共有多少个中心块、棱块和角块呢?

输入
一个整数N.

输出
共三行,分别输出N阶魔方的中心块数、棱块数和角块数。

样例输入1
3

样例输出1
6
12
8

小数据范围:2≤N≤5
中数据范围:2≤N≤10^9
大数据范围:2≤N≤10^5109

A(小数据) :

#include<bits/stdc++.h>using namespace std;int main() {    int n;    cin >> n;   // 也可暴力枚举不多的所有情况    int x = (n-2) * (n-2) * 6;    int y = 12 * (n - 2);    int z = 8;    cout << x << endl;    cout << y << endl;    cout << z << endl;    return 0;}

A(中数据) :

#include<bits/stdc++.h>using namespace std;int main() {    long long n;    cin >> n;    long long x = (n-2) * (n-2) * 6;    //范围超了int,在long long 内    long long y = 12 * n - 24;    long long z = 8;    cout << x << endl;    cout << y << endl;    cout << z << endl;    return 0;}

A(大数据) :

#include<bits/stdc++.h>using namespace std;int a[12000],b[12000],z[12000],l[12000]; //位数int main(){    string s;   // 大数以字符串形式读入    cin >> s;    int len = s.length();    bool flag;    for (int i = 0;i < len; ++i) {  // 字符反转,从最后一位操作数开始        a[i] = s[len-1-i] - 48;        b[i] = a[i];    }    b[0]-=2;    // n-2    int j = 0;    while (b[j] < 0) {  // 处理个位为0,1的情况,十位减1来补,以此往前类推        b[j] += 10;        ++j;        --b[j];    }    for (int i = 0; i < len; ++i) {            l[i] = b[i] *12;    //  逐位相乘12 12 * (n-2)    }    for (int i = 0; i < len + 2; ++i) { // 乘数为12,位数增加不多于2位 +2        j = l[i] / 10;        l[i] %= 10;        l[i+1] += j;  // 进位    }    for (int i = 0; i < len; ++i) {        for(int j=0; j < len; ++j) {            z[i+j] += b[i] * b[j];  // (n-2) * (n-2)        }    }    for (int i=0; i < 2*len; ++i) {         z[i] *= 6; //6 * (n-2) * (n-2)    }    for (int i = 0; i < 2*len; ++i) {        j = z[i] / 10;        z[i] %= 10;        z[i+1] += j;    }    flag = 0;    for (int i = 11111; i >= 0; --i) {  // 取大于可能长度的数,个位下标为0,反着输入的时候从头输出        if (i == 0 || z[i]) flag = 1;  //前导0不输出,从一个很高的位找到一个不为0的数开始输出,后面的数包括是0都要输出        if (flag) printf("%d", z[i]);    }    printf("\n");    flag = 0;    for(int i = 11111; i >= 0; --i) {        if (i==0 || l[i]) flag = 1;        if (flag) printf("%d", l[i]);    }    printf("\n");    cout << "8" << endl;    return 0;}

数据范围很大时,需要考虑高精度运算了。