• 【FJOI2007】轮状病毒


    题目描述

    轮状病毒有很多变种。许多轮状病毒都是由一个轮状基产生。一个n轮状基由圆环上n个不同的基原子和圆心的一个核原子构成。2个原子之间的边表示这2个原子之间的信息通道,如下图所示。

    n轮状病毒的产生规律是在n轮状基中删除若干边,使各原子之间有唯一一条信息通道。例如,共有16个不同的3轮状病毒,如下图所示。

    给定n(N<=100),编程计算有多少个不同的n轮状病毒。

    思路

    结论 $ f_{n} = f_{n-2} imes 3 - f_{n-1} + 2 $ (Matrix-Tree 定理推出来了,不会 233)

    要写高精

    #include <bits/stdc++.h>
    using namespace std;
    struct bign {
        int d[100], len;
        void clean() { while(len > 1 && !d[len-1]) len--; }
        bign() { memset(d, 0, sizeof(d)); len = 1; }
        bign(int num) { *this = num; }
        bign(char* num) { *this = num; }
        bign operator = (const char* num) {
            memset(d, 0, sizeof(d)); len = strlen(num);
            for(int i = 0; i < len; i++) d[i] = num[len-1-i] - '0';
            clean();
            return *this;
        }
        bign operator = (int num){
            char s[20]; sprintf(s, "%d", num);
            *this = s;
            return *this;
        }
        bign operator + (const bign& b){
            bign c = *this; int i;
            for (i = 0; i < b.len; i++){
                c.d[i] += b.d[i];
                if (c.d[i] > 9) c.d[i]%=10, c.d[i+1]++;
            }
            while (c.d[i] > 9) c.d[i++]%=10, c.d[i]++;
            c.len = max(len, b.len);
            if (c.d[i] && c.len <= i) c.len = i+1;
            return c;
        }
        bign operator - (const bign& b){
            bign c = *this; int i;
            for (i = 0; i < b.len; i++){
                c.d[i] -= b.d[i];
                if (c.d[i] < 0) c.d[i]+=10, c.d[i+1]--;
            }
            while (c.d[i] < 0) c.d[i++]+=10, c.d[i]--;
            c.clean();
            return c;
        }  
        bign operator * (const bign& b)const{
            int i, j; bign c; c.len = len + b.len;
            for(j = 0; j < b.len; j++) for(i = 0; i < len; i++)
                c.d[i+j] += d[i] * b.d[j];
            for(i = 0; i < c.len-1; i++)
                c.d[i+1] += c.d[i]/10, c.d[i] %= 10;
            c.clean();
            return c;
        }
    }a,b,c;
    int main() {
        int n;
        scanf("%d",&n);
        b = 5,c = 1;
        if (n < 3) {
            printf("%d",n == 2 ? 5 : 1);
            return 0;
        }
        for (int i = 3;i <= n;i++) {
            a = b*3-c+2;
            c = b;
            b = a;
        }
        for (int i = a.len-1;i >= 0;i--) printf("%d",a.d[i]);
        return 0;
    }
  • 相关阅读:
    unity3d优化-代码篇(不定期更新)
    Activity的生命周期
    继承了AppCompatActivity的全屏设置
    shaderlab UV动画所需的变量声明
    加载Assetbundle需要注意的地方
    VisualStudio中的编辑后期生成事件
    unity3D射线检测敌人是否在前方
    Unity3D 定时发射子弹
    Unity3D使用NGUI做个弹窗
    Unity3D TouchScript 插件教程一
  • 原文地址:https://www.cnblogs.com/lrj124/p/8971219.html
Copyright © 2020-2023  润新知