烷烃同分异构体数目的计算

烷烃同分异构体数目的计算

相信大家在学习高中的有机化学时,老师一定会给你讲过一类找烷烃同分异构体的题目吧?

而且老师还会说这种题只能靠动手画图,没有数学公式来计算,只有画的做到不重复不遗漏考试才能得到分。不少人为此绞尽脑汁。那么如果我们想知道几十个C原子能组成多少同分异构体怎么办呢?要一个一个地画吗?那估计穷尽一生也画不完。因为烷烃同分异构的数目变化和C原子的数目是不成线性变化的。

那么就没有计算的方法了吗?

其实不然,我么可以用Polya计数定理来推算烷烃同分异构的数目。
当然在这里我就不赘述数学上的证明了,有兴趣的小伙伴可以自行查阅有关书籍。

这个代码段通过高精度模版实现了任意碳原子数目构成同分异构体数目的计算。
它把同分异构体数目的计算巧妙等价转换成了烷基数目的计算,大大简化了计算难度。
然而,由于该算法存在不小的时间复杂度,也许1000以上个C原子组成的烷烃会计算很长时间。

源代码如下          注意:只能计算出链结构的烷烃

#include <iostream>
#include <cstring>

#define DIGIT    4
#define DEPTH    10000
#define MAX     100
using namespace std;
typedef int bignum_t[MAX + 1];
int read(bignum_t a, istream& is = cin) {
    char buf[MAX * DIGIT + 1], ch;
    int i, j;
    memset((void*)a, 0, sizeof(bignum_t));
    if (!(is >> buf))    return 0;
    for (a[0] = strlen(buf), i = a[0] / 2 - 1; i >= 0; i--)
        ch = buf[i], buf[i] = buf[a[0] - 1 - i], buf[a[0] - 1 - i] = ch;
    for (a[0] = (a[0] + DIGIT - 1) / DIGIT, j = strlen(buf); j < a[0] * DIGIT; buf[j++] = '0');
    for (i = 1; i <= a[0]; i++)
        for (a[i] = 0, j = 0; j < DIGIT; j++)
            a[i] = a[i] * 10 + buf[i * DIGIT - 1 - j] - '0';
    for (; !a[a[0]] && a[0] > 1; a[0]--);
    return 1;
}
void write(const bignum_t a, ostream& os = cout) {
    int i, j;
    for (os << a[i = a[0]], i--; i; i--)
        for (j = DEPTH / 10; j; j /= 10)
            os << a[i] / j % 10;
}
int comp(const bignum_t a, const bignum_t b) {
    int i;
    if (a[0] != b[0])
        return a[0] - b[0];
    for (i = a[0]; i; i--)
        if (a[i] != b[i])
            return a[i] - b[i];
    return 0;
}
int comp(const bignum_t a, const int b) {
    int c[12] = { 1 };
    for (c[1] = b; c[c[0]] >= DEPTH; c[c[0] + 1] = c[c[0]] / DEPTH, c[c[0]] %= DEPTH, c[0]++);
    return comp(a, c);
}
int comp(const bignum_t a, const int c, const int d, const bignum_t b) {
    int i, t = 0, O = -DEPTH * 2;
    if (b[0] - a[0] < d && c)
        return 1;
    for (i = b[0]; i > d; i--) {
        t = t * DEPTH + a[i - d] * c - b[i];
        if (t > 0) return 1;
        if (t < O) return 0;
    }
    for (i = d; i; i--) {
        t = t * DEPTH - b[i];
        if (t > 0) return 1;
        if (t < O) return 0;
    }
    return t > 0;
}
void add(bignum_t a, const bignum_t b) {
    int i;
    for (i = 1; i <= b[0]; i++)
        if ((a[i] += b[i]) >= DEPTH)
            a[i] -= DEPTH, a[i + 1]++;
    if (b[0] >= a[0])
        a[0] = b[0];
    else
        for (; a[i] >= DEPTH && i < a[0]; a[i] -= DEPTH, i++, a[i]++);
    a[0] += (a[a[0] + 1] > 0);
}
void add(bignum_t a, const int b) {
    int i = 1;
    for (a[1] += b; a[i] >= DEPTH && i < a[0]; a[i + 1] += a[i] / DEPTH, a[i] %= DEPTH, i++);
    for (; a[a[0]] >= DEPTH; a[a[0] + 1] = a[a[0]] / DEPTH, a[a[0]] %= DEPTH, a[0]++);
}
void sub(bignum_t a, const bignum_t b) {
    int i;
    for (i = 1; i <= b[0]; i++)
        if ((a[i] -= b[i]) < 0)
            a[i + 1]--, a[i] += DEPTH;
    for (; a[i] < 0; a[i] += DEPTH, i++, a[i]--);
    for (; !a[a[0]] && a[0] > 1; a[0]--);
}
void sub(bignum_t a, const int b) {
    int i = 1;
    for (a[1] -= b; a[i] < 0; a[i + 1] += (a[i] - DEPTH + 1) / DEPTH, a[i] -= (a[i] - DEPTH + 1) / DEPTH * DEPTH, i++);
    for (; !a[a[0]] && a[0] > 1; a[0]--);
}
void sub(bignum_t a, const bignum_t b, const int c, const int d) {
    int i, O = b[0] + d;
    for (i = 1 + d; i <= O; i++)
        if ((a[i] -= b[i - d] * c) < 0)
            a[i + 1] += (a[i] - DEPTH + 1) / DEPTH, a[i] -= (a[i] - DEPTH + 1) / DEPTH * DEPTH;
    for (; a[i] < 0; a[i + 1] += (a[i] - DEPTH + 1) / DEPTH, a[i] -= (a[i] - DEPTH + 1) / DEPTH * DEPTH, i++);
    for (; !a[a[0]] && a[0] > 1; a[0]--);
}
void mul(bignum_t c, const bignum_t a, const bignum_t b) {
    int i, j;
    memset((void*)c, 0, sizeof(bignum_t));
    for (c[0] = a[0] + b[0] - 1, i = 1; i <= a[0]; i++)
        for (j = 1; j <= b[0]; j++)
            if ((c[i + j - 1] += a[i] * b[j]) >= DEPTH)
                c[i + j] += c[i + j - 1] / DEPTH, c[i + j - 1] %= DEPTH;
    for (c[0] += (c[c[0] + 1] > 0); !c[c[0]] && c[0] > 1; c[0]--);
}
void mul(bignum_t a, const int b) {
    int i;
    for (a[1] *= b, i = 2; i <= a[0]; i++) {
        a[i] *= b;
        if (a[i - 1] >= DEPTH)
            a[i] += a[i - 1] / DEPTH, a[i - 1] %= DEPTH;
    }
    for (; a[a[0]] >= DEPTH; a[a[0] + 1] = a[a[0]] / DEPTH, a[a[0]] %= DEPTH, a[0]++);
    for (; !a[a[0]] && a[0] > 1; a[0]--);
}
void mul(bignum_t b, const bignum_t a, const int c, const int d) {
    int i;
    memset((void*)b, 0, sizeof(bignum_t));
    for (b[0] = a[0] + d, i = d + 1; i <= b[0]; i++)
        if ((b[i] += a[i - d] * c) >= DEPTH)
            b[i + 1] += b[i] / DEPTH, b[i] %= DEPTH;
    for (; b[b[0] + 1]; b[0]++, b[b[0] + 1] = b[b[0]] / DEPTH, b[b[0]] %= DEPTH);
    for (; !b[b[0]] && b[0] > 1; b[0]--);
}
void div(bignum_t c, bignum_t a, const bignum_t b) {
    int h, l, m, i;
    memset((void*)c, 0, sizeof(bignum_t));
    c[0] = (b[0] < a[0] + 1) ? (a[0] - b[0] + 2) : 1;
    for (i = c[0]; i; sub(a, b, c[i] = m, i - 1), i--)
        for (h = DEPTH - 1, l = 0, m = (h + l + 1) >> 1; h > l; m = (h + l + 1) >> 1)
            if (comp(b, m, i - 1, a)) h = m - 1;
            else l = m;
    for (; !c[c[0]] && c[0] > 1; c[0]--);
    c[0] = c[0] > 1 ? c[0] : 1;
}
void div(bignum_t a, const int b, int& c) {
    int i;
    for (c = 0, i = a[0]; i; c = c * DEPTH + a[i], a[i] = c / b, c %= b, i--);
    for (; !a[a[0]] && a[0] > 1; a[0]--);
}
void sqrt(bignum_t b, bignum_t a) {
    int h, l, m, i;
    memset((void*)b, 0, sizeof(bignum_t));
    for (i = b[0] = (a[0] + 1) >> 1; i; sub(a, b, m, i - 1), b[i] += m, i--)
        for (h = DEPTH - 1, l = 0, b[i] = m = (h + l + 1) >> 1; h > l; b[i] = m = (h + l + 1) >> 1)
            if (comp(b, m, i - 1, a)) h = m - 1;
            else l = m;
    for (; !b[b[0]] && b[0] > 1; b[0]--);
    for (i = 1; i <= b[0]; b[i++] >>= 1);
}
int length(const bignum_t a) {
    int t, ret;
    for (ret = (a[0] - 1) * DIGIT, t = a[a[0]]; t; t /= 10, ret++);
    return ret > 0 ? ret : 1;
}
int digit(const bignum_t a, const int b) {
    int i, ret;
    for (ret = a[(b - 1) / DIGIT + 1], i = (b - 1) % DIGIT; i; ret /= 10, i--);
    return ret % 10;
}
int zeronum(const bignum_t a) {
    int ret, t;
    for (ret = 0; !a[ret + 1]; ret++);
    for (t = a[ret + 1], ret *= DIGIT; !(t % 10); t /= 10, ret++);
    return ret;
}
void comp(int* a, const int l, const int h, const int d) {
    int i, j, t;
    for (i = l; i <= h; i++)
        for (t = i, j = 2; t > 1; j++)
            while (!(t % j))
                a[j] += d, t /= j;
}
void convert(int* a, const int h, bignum_t b) {
    int i, j, t = 1;
    memset(b, 0, sizeof(bignum_t));
    for (b[0] = b[1] = 1, i = 2; i <= h; i++)
        if (a[i])
            for (j = a[i]; j; t *= i, j--)
                if (t * i > DEPTH)
                    mul(b, t), t = 1;
    mul(b, t);
}
void combination(bignum_t a, int m, int n) {
    int* t = new int[m + 1];
    memset((void*)t, 0, sizeof(int) * (m + 1));
    comp(t, n + 1, m, 1);
    comp(t, 2, m - n, -1);
    convert(t, m, a);
    delete[]t;
}
void permutation(bignum_t a, int m, int n) {
    int i, t = 1;
    memset(a, 0, sizeof(bignum_t));
    a[0] = a[1] = 1;
    for (i = m - n + 1; i <= m; t *= i++)
        if (t * i > DEPTH)
            mul(a, t), t = 1;
    mul(a, t);
}

#define SGN(x) ((x)>0?1:((x)<0?-1:0))
#define ABS(x) ((x)>0?(x):-(x))

int read(bignum_t a, int& sgn, istream& is = cin) {
    char str[MAX * DIGIT + 2], ch, * buf;
    int i, j;
    memset((void*)a, 0, sizeof(bignum_t));
    if (!(is >> str)) return 0;
    buf = str, sgn = 1;
    if (*buf == '-') sgn = -1, buf++;
    for (a[0] = strlen(buf), i = a[0] / 2 - 1; i >= 0; i--)
        ch = buf[i], buf[i] = buf[a[0] - 1 - i], buf[a[0] - 1 - i] = ch;
    for (a[0] = (a[0] + DIGIT - 1) / DIGIT, j = strlen(buf); j < a[0] * DIGIT; buf[j++] = '0');
    for (i = 1; i <= a[0]; i++)
        for (a[i] = 0, j = 0; j < DIGIT; j++)
            a[i] = a[i] * 10 + buf[i * DIGIT - 1 - j] - '0';
    for (; !a[a[0]] && a[0] > 1; a[0]--);
    if (a[0] == 1 && !a[1]) sgn = 0;
    return 1;
}
struct bignum {
    bignum_t num;
    int sgn;
public:
    inline bignum() { memset(num, 0, sizeof(bignum_t)); num[0] = 1; sgn = 0; }
    inline int operator!() { return num[0] == 1 && !num[1]; }
    inline bignum& operator=(const bignum& a) { memcpy(num, a.num, sizeof(bignum_t)); sgn = a.sgn; return *this; }
    inline bignum& operator=(const int a) { memset(num, 0, sizeof(bignum_t)); num[0] = 1; sgn = SGN(a); add(num, sgn * a); return *this; };
    inline bignum& operator+=(const bignum& a) {
        if (sgn == a.sgn)add(num, a.num); else if (sgn && a.sgn) {
            int ret = comp(num, a.num); if (ret > 0)sub(num, a.num); else if (ret < 0) {
                bignum_t t;
                memcpy(t, num, sizeof(bignum_t)); memcpy(num, a.num, sizeof(bignum_t)); sub(num, t); sgn = a.sgn;
            }
            else memset(num, 0, sizeof(bignum_t)), num[0] = 1, sgn = 0;
        }
        else if (!sgn)memcpy(num, a.num, sizeof(bignum_t)), sgn = a.sgn; return *this;
    }
    inline bignum& operator+=(const int a) {
        if (sgn * a > 0)add(num, ABS(a)); else if (sgn && a) {
            int ret = comp(num, ABS(a)); if (ret > 0)sub(num, ABS(a)); else if (ret < 0) {
                bignum_t t;
                memcpy(t, num, sizeof(bignum_t)); memset(num, 0, sizeof(bignum_t)); num[0] = 1; add(num, ABS(a)); sgn = -sgn; sub(num, t);
            }
            else memset(num, 0, sizeof(bignum_t)), num[0] = 1, sgn = 0;
        }
        else if (!sgn)sgn = SGN(a), add(num, ABS(a)); return *this;
    }
    inline bignum operator+(const bignum& a) { bignum ret; memcpy(ret.num, num, sizeof(bignum_t)); ret.sgn = sgn; ret += a; return ret; }
    inline bignum operator+(const int a) { bignum ret; memcpy(ret.num, num, sizeof(bignum_t)); ret.sgn = sgn; ret += a; return ret; }
    inline bignum& operator-=(const bignum& a) {
        if (sgn * a.sgn < 0)add(num, a.num); else if (sgn && a.sgn) {
            int ret = comp(num, a.num); if (ret > 0)sub(num, a.num); else if (ret < 0) {
                bignum_t t;
                memcpy(t, num, sizeof(bignum_t)); memcpy(num, a.num, sizeof(bignum_t)); sub(num, t); sgn = -sgn;
            }
            else memset(num, 0, sizeof(bignum_t)), num[0] = 1, sgn = 0;
        }
        else if (!sgn)add(num, a.num), sgn = -a.sgn; return *this;
    }
    inline bignum& operator-=(const int a) {
        if (sgn * a < 0)add(num, ABS(a)); else if (sgn && a) {
            int ret = comp(num, ABS(a)); if (ret > 0)sub(num, ABS(a)); else if (ret < 0) {
                bignum_t t;
                memcpy(t, num, sizeof(bignum_t)); memset(num, 0, sizeof(bignum_t)); num[0] = 1; add(num, ABS(a)); sub(num, t); sgn = -sgn;
            }
            else memset(num, 0, sizeof(bignum_t)), num[0] = 1, sgn = 0;
        }
        else if (!sgn)sgn = -SGN(a), add(num, ABS(a)); return *this;
    }
    inline bignum operator-(const bignum& a) { bignum ret; memcpy(ret.num, num, sizeof(bignum_t)); ret.sgn = sgn; ret -= a; return ret; }
    inline bignum operator-(const int a) { bignum ret; memcpy(ret.num, num, sizeof(bignum_t)); ret.sgn = sgn; ret -= a; return ret; }
    inline bignum& operator*=(const bignum& a) { bignum_t t; mul(t, num, a.num); memcpy(num, t, sizeof(bignum_t)); sgn *= a.sgn; return *this; }
    inline bignum& operator*=(const int a) { mul(num, ABS(a)); sgn *= SGN(a); return *this; }
    inline bignum operator*(const bignum& a) { bignum ret; mul(ret.num, num, a.num); ret.sgn = sgn * a.sgn; return ret; }
    inline bignum operator*(const int a) { bignum ret; memcpy(ret.num, num, sizeof(bignum_t)); mul(ret.num, ABS(a)); ret.sgn = sgn * SGN(a); return ret; }
    inline bignum& operator/=(const bignum& a) { bignum_t t; div(t, num, a.num); memcpy(num, t, sizeof(bignum_t)); sgn = (num[0] == 1 && !num[1]) ? 0 : sgn * a.sgn; return *this; }
    inline bignum& operator/=(const int a) { int t; div(num, ABS(a), t); sgn = (num[0] == 1 && !num[1]) ? 0 : sgn * SGN(a); return *this; }
    inline bignum operator/(const bignum& a) { bignum ret; bignum_t t; memcpy(t, num, sizeof(bignum_t)); div(ret.num, t, a.num); ret.sgn = (ret.num[0] == 1 && !ret.num[1]) ? 0 : sgn * a.sgn; return ret; }
    inline bignum operator/(const int a) { bignum ret; int t; memcpy(ret.num, num, sizeof(bignum_t)); div(ret.num, ABS(a), t); ret.sgn = (ret.num[0] == 1 && !ret.num[1]) ? 0 : sgn * SGN(a); return ret; }
    inline bignum& operator%=(const bignum& a) { bignum_t t; div(t, num, a.num); if (num[0] == 1 && !num[1])sgn = 0; return *this; }
    inline int operator%=(const int a) { int t; div(num, ABS(a), t); memset(num, 0, sizeof(bignum_t)); num[0] = 1; add(num, t); return t; }
    inline bignum operator%(const bignum& a) { bignum ret; bignum_t t; memcpy(ret.num, num, sizeof(bignum_t)); div(t, ret.num, a.num); ret.sgn = (ret.num[0] == 1 && !ret.num[1]) ? 0 : sgn; return ret; }
    inline int operator%(const int a) { bignum ret; int t; memcpy(ret.num, num, sizeof(bignum_t)); div(ret.num, ABS(a), t); memset(ret.num, 0, sizeof(bignum_t)); ret.num[0] = 1; add(ret.num, t); return t; }
    inline bignum& operator++() { *this += 1; return *this; }
    inline bignum& operator--() { *this -= 1; return *this; };
    inline int operator>(const bignum& a) { return sgn > 0 ? (a.sgn > 0 ? comp(num, a.num) > 0:1) : (sgn < 0 ? (a.sgn < 0 ? comp(num, a.num) < 0 : 0) : a.sgn < 0); }
    inline int operator>(const int a) { return sgn > 0 ? (a > 0 ? comp(num, a) > 0:1) : (sgn < 0 ? (a < 0 ? comp(num, -a) < 0 : 0) : a < 0); }
    inline int operator>=(const bignum& a) { return sgn > 0 ? (a.sgn > 0 ? comp(num, a.num) >= 0 : 1) : (sgn < 0 ? (a.sgn < 0 ? comp(num, a.num) <= 0 : 0) : a.sgn <= 0); }
    inline int operator>=(const int a) { return sgn > 0 ? (a > 0 ? comp(num, a) >= 0 : 1) : (sgn < 0 ? (a < 0 ? comp(num, -a) <= 0 : 0) : a <= 0); }
    inline int operator<(const bignum& a) { return sgn < 0 ? (a.sgn < 0 ? comp(num, a.num)>0:1) : (sgn > 0 ? (a.sgn > 0 ? comp(num, a.num) < 0 : 0) : a.sgn > 0); }
    inline int operator<(const int a) { return sgn < 0 ? (a < 0 ? comp(num, -a)>0:1) : (sgn > 0 ? (a > 0 ? comp(num, a) < 0 : 0) : a > 0); }
    inline int operator<=(const bignum& a) { return sgn < 0 ? (a.sgn < 0 ? comp(num, a.num) >= 0 : 1) : (sgn > 0 ? (a.sgn > 0 ? comp(num, a.num) <= 0 : 0) : a.sgn >= 0); }
    inline int operator<=(const int a) { return sgn < 0 ? (a < 0 ? comp(num, -a) >= 0 : 1) : (sgn > 0 ? (a > 0 ? comp(num, a) <= 0 : 0) : a >= 0); }
    inline int operator==(const bignum& a) { return (sgn == a.sgn) ? !comp(num, a.num) : 0; }
    inline int operator==(const int a) { return (sgn * a >= 0) ? !comp(num, ABS(a)) : 0; }
    inline int operator!=(const bignum& a) { return (sgn == a.sgn) ? comp(num, a.num) : 1; }
    inline int operator!=(const int a) { return (sgn * a >= 0) ? comp(num, ABS(a)) : 1; }
    inline int operator[](const int a) { return digit(num, a); }
    friend inline istream& operator>>(istream& is, bignum& a) { read(a.num, a.sgn, is); return is; }
    friend inline ostream& operator<<(ostream& os, const bignum& a) { if (a.sgn < 0)os << '-'; write(a.num, os); return os; }
    friend inline bignum sqrt(const bignum& a) { bignum ret; bignum_t t; memcpy(t, a.num, sizeof(bignum_t)); sqrt(ret.num, t); ret.sgn = ret.num[0] != 1 || ret.num[1]; return ret; }
    friend inline bignum sqrt(const bignum& a, bignum& b) { bignum ret; memcpy(b.num, a.num, sizeof(bignum_t)); sqrt(ret.num, b.num); ret.sgn = ret.num[0] != 1 || ret.num[1]; b.sgn = b.num[0] != 1 || ret.num[1]; return ret; }
    inline int length() { return ::length(num); }
    inline int zeronum() { return ::zeronum(num); }
    inline bignum C(const int m, const int n) { combination(num, m, n); sgn = 1; return *this; }
    inline bignum P(const int m, const int n) { permutation(num, m, n); sgn = 1; return *this; }
};
//以上为高精度模板 
typedef bignum ll;

ll x1[10001], x2[10001], x3[10001], tot[10001];//x1为1°烷基个数,x2为2°烷基个数,x3为3°烷基个数,tot为烷基个数之和,序数为碳数 
void f_calc_alkyl(int n) {
    x1[1] = 1; tot[1] = 1;
    x1[2] = 1; tot[2] = 1;
    x1[3] = 1; x2[3] = 1; tot[3] = 2;
    x1[4] = 2; x2[4] = 1; x3[4] = 1; tot[4] = 4;
    //初始化1到4碳的烷基种类 
    for (int i = 5; i <= n; i++)
    {
        x1[i] = tot[i - 1];
        //计算1°烷基种类 
        for (int j = 1; j < (i - 1) / 2; j++)
        {
            x2[i] += tot[j] * tot[i - 1 - j];
        }
        if (i % 2)
            x2[i] += tot[(i - 1) / 2] * (tot[(i - 1) / 2] + 1) / 2;
        else
            x2[i] += tot[i / 2] * tot[i / 2 - 1];
        //计算2°烷基种类 
        for (int j = 1; j < i; j++)
        {
            for (int k = j + 1; k < i; k++)
            {
                if (i - 1 - j - k > k)
                {
                    x3[i] += tot[j] * tot[k] * tot[i - 1 - j - k];
                }
            }
        }
        //连接的3个烷基为ABC型 
        for (int j = 1; j < i && i - 1 - 2 * j>0; j++)
        {
            if (j != i - 1 - 2 * j)
                x3[i] += (tot[j] * (tot[j] + 1)) / 2 * tot[i - 1 - 2 * j];
        }
        //连接的3个烷基为AAB型 
        if ((i - 1) % 3 == 0)
        {
            int tem = (i - 1) / 3;
            x3[i] += tot[tem] * (tot[tem] + 1) * (tot[tem] + 2) / 6;
        }
        //连接的3个烷基为AAA型 
        //计算3°烷基种类 
        tot[i] = x1[i] + x2[i] + x3[i];
        //求和 
    }
}
//计算烷基个数 
bignum f_calc_3(int n) {
    bignum ans;
    ans = 0;
    int ub = (n + 1) / 2;//所连烷基碳数上限 
    for (int i = 1; i < ub; i++)
    {
        for (int j = i + 1; j < ub; j++)
        {
            if (n - i - j > j && n - i - j < ub)
                ans = ans + tot[i] * tot[j] * tot[n - i - j];
        }
    }
    //烷基为ABC型 
    for (int i = 1; i < ub; i++)
    {
        if (n - 2 * i > 0 && n - 2 * i < ub && i != n - 2 * i)
            ans = ans + (tot[i] + 1) * tot[i] / 2 * tot[n - 2 * i];
    }
    //烷基为AAB型 
    if (n % 3 == 0)
        ans = ans + tot[n / 3] * (tot[n / 3] + 1) * (tot[n / 3] + 2) / 6;
    //烷基为AAA型
    return ans;
}
// 计算中心为3°碳的烷烃个数 
bignum f_calc_4(int n) {
    bignum ans;
    ans = 0;
    int ub = (n + 1) / 2;
    for (int i = 1; i < ub; i++) {
        for (int j = i + 1; j < ub; j++)
        {
            for (int k = j + 1; k < ub; k++)
            {
                if (n - i - j - k > k && n - i - j - k < ub)
                    ans += tot[i] * tot[j] * tot[k] * tot[n - i - j - k];
            }
        }
    }//烷基为ABCD型 
    for (int i = 1; i < ub; i++) {
        for (int j = 1; j < ub; j++)
        {
            if (n - 2 * i - j > j && i != j && i != n - 2 * i - j && n - 2 * i - j < ub)
                ans += tot[i] * (tot[i] + 1) / 2 * tot[j] * tot[n - 2 * i - j];
        }
    }//烷基为AABC型 
    if (n % 2 == 0) {
        int tem = n / 2;
        for (int i = 1; i < tem - i; i++)
            ans += tot[i] * (tot[i] + 1) / 2 * tot[tem - i] * (tot[tem - i] + 1) / 2;
    }//烷基为AABB型 
    for (int i = 1; i <= n && n - 3 * i > 0; i++) {
        if (i != n - 3 * i && n - 3 * i < ub)
            ans += tot[i] * (tot[i] + 1) * (tot[i] + 2) / 6 * tot[n - 3 * i];
    }//烷基为AAAB型 
    if (n % 4 == 0) {
        ans += tot[n / 4] * (tot[n / 4] + 1) * (tot[n / 4] + 2) * (tot[n / 4] + 3) / 24;
    }//烷基为AAAA型 
    return ans;
}
// 计算中心为4°碳的烷烃个数 
bignum f_calc_odd(int n) {
    bignum ans = tot[n / 2] * (tot[n / 2] + 1) / 2 + tot[n / 2] * (tot[n / 2 + 1] - tot[n / 2]);
    ans += f_calc_3(n - 1);
    ans += f_calc_4(n - 1);
    return ans;
}
bignum f_calc_even(int n) {
    bignum ans = (tot[n / 2] + 1) * tot[n / 2] / 2;
    ans += f_calc_3(n - 1);
    ans += f_calc_4(n - 1);
    return ans;
}
bignum f_calc(int n) {
    f_calc_alkyl(n);
    if (n % 2 == 0)
        return f_calc_even(n);
    else
        return f_calc_odd(n);
    //分奇偶讨论 
}
int main()
{

    int num;
    cout << "请输入C原子的个数  " << endl;
    cin >> num;
    cout <<endl <<"能构成同分异构体的数目为" << f_calc(num) << endl;
}

输入:C原子的个数

输出:该C原子数目所能构成链结构烷烃同分异构体的数目

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Navicat 多源异构是指Navicat数据库管理工具支持多种类型的数据库,并且可以进行跨数据库之间的数据转换和同步。 不同类型的数据库,比如MySQL、Oracle、SQL Server等,拥有不同的存储结构和查询语法。Navicat通过自身的多源异构功能,可以连接这些不同类型的数据库,并且在进行数据管理和操作时,提供统一的界面和操作方式。 通过Navicat的多源异构功能,用户可以方便地在不同类型的数据库之间进行数据转换和同步。比如,可以将MySQL数据库中的数据导入到Oracle数据库中,或者将SQL Server数据库中的表结构和数据复制到MySQL数据库中。这样,用户可以轻松地实现不同数据库之间的数据迁移和同步。 此外,Navicat还支持对不同类型的数据库进行比较和同步操作。用户可以通过比较功能,快速发现不同数据库中的数据差异,然后使用同步功能将数据进行统一。这样,用户可以确保不同数据库之间的数据一致性。 总之,Navicat的多源异构功能为用户提供了一个便捷的数据库管理工具,可以连接和管理多种类型的数据库,并且支持数据转换和同步操作,帮助用户更高效地进行数据库管理和操作。 ### 回答2: Navicat 多源异构是指Navicat数据库管理工具支持同时连接多种不同类型的数据库,并能在这些数据库之间进行数据转换和同步的功能。它的主要特点包括: 1. 支持多种数据库类型:Navicat能够连接和管理主流数据库类型,包括MySQL、SQL Server、Oracle和PostgreSQL等。这让用户能够通过一个工具管理不同类型的数据库,方便快捷。 2. 数据传输和同步:Navicat能够实现不同数据库之间的数据传输和同步,无论是同种数据库之间还是不同数据库之间。用户可以自由选择源数据库和目标数据库,进行数据的复制、迁移和同步。 3. 数据库结构转换:Navicat还提供了将不同数据库之间的数据库结构转换的功能。用户可以将一个数据库中的表、索引、视图等结构转换到另一个数据库中,节省了重新创建数据库对象的时间和工作量。 4. 数据库管理工具:除了上述功能外,Navicat还具备完善的数据库管理工具,包括数据库的创建、修改和删除,表的创建、修改和删除,视图的创建和管理,用户和权限的管理等。用户可以通过Navicat轻松地进行数据库的管理和维护工作。 总结来说,Navicat 多源异构的功能使得数据库管理员和开发人员能够更加方便地管理和操作多种不同类型的数据库,简化了数据库转换和同步的过程,提高了工作效率。 ### 回答3: Navicat是一款流行的数据库管理工具,它支持多种数据库类型,包括MySQL、Oracle、SQL Server等。所以我们可以说Navicat是一种多源异构的工具。 "多源"指的是Navicat可以连接和管理不同种类的数据库。无论你使用的是哪个数据库,你都可以使用Navicat来查看、编辑和管理数据。这使得Navicat成为处理数据库异构环境的理想工具。例如,你可能会在一个项目中同时使用MySQL和Oracle数据库,而不需要切换不同的工具来管理这些数据库。 "异构"表示Navicat可以处理各种类型的数据库,即使它们在结构、语法和功能上有所不同。Navicat提供了一个统一的界面和功能集,无论你使用的是哪种数据库,你都可以使用相同的方法和工具来管理它们。这使得学习和使用Navicat变得更加方便和高效。 总之,Navicat作为一种多源异构的数据库管理工具,提供了跨多种类型数据库的连接和管理功能。它简化了处理数据库异构环境的工作,提高了生产效率,并为用户提供了一种统一和方便的数据库管理验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值