zoukankan      html  css  js  c++  java
  • BZOJ1002:[FJOI2007]轮状病毒(找规律,递推)

    Description

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

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

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

    Input

      第一行有1个正整数n

    Output

      计算出的不同的n轮状病毒数输出

    Sample Input

    3

    Sample Output

    16

    Solution

    数论推个P,打表找规律
    emmm听说这个题要用矩阵树定理……我不会啊……
    然后我就去找题解想学一下……然后就看到了一篇找规律的题解……
    f[1]=1,f[2]=3,答案就是斐波那契数列的第n项的平方,如果n是偶数还要再减4
    高精度都懒得打了……直接搬了一个
    啥?矩阵树?以后再说吧

    Code

      1 #include <iostream>
      2 #include <cstdio>
      3 #include <cstdlib>
      4 #include <cstring>
      5 #include <string>
      6 #include <algorithm>
      7 using namespace std;
      8 
      9 const int MAXN = 410;
     10 
     11 struct bign
     12 {
     13     int len, s[MAXN];
     14     bign ()
     15     {
     16         memset(s, 0, sizeof(s));
     17         len = 1;
     18     }
     19     bign (int num) { *this = num; }
     20     bign (const char *num) { *this = num; }
     21     bign operator = (const int num)
     22     {
     23         char s[MAXN];
     24         sprintf(s, "%d", num);
     25         *this = s;
     26         return *this;
     27     }
     28     bign operator = (const char *num)
     29     {
     30         for(int i = 0; num[i] == '0'; num++) ;  //去前导0
     31         len = strlen(num);
     32         for(int i = 0; i < len; i++) s[i] = num[len-i-1] - '0';
     33         return *this;
     34     }
     35     bign operator + (const bign &b) const //+
     36     {
     37         bign c;
     38         c.len = 0;
     39         for(int i = 0, g = 0; g || i < max(len, b.len); i++)
     40         {
     41             int x = g;
     42             if(i < len) x += s[i];
     43             if(i < b.len) x += b.s[i];
     44             c.s[c.len++] = x % 10;
     45             g = x / 10;
     46         }
     47         return c;
     48     }
     49     bign operator += (const bign &b)
     50     {
     51         *this = *this + b;
     52         return *this;
     53     }
     54     void clean()
     55     {
     56         while(len > 1 && !s[len-1]) len--;
     57     }
     58     bign operator * (const bign &b) //*
     59     {
     60         bign c;
     61         c.len = len + b.len;
     62         for(int i = 0; i < len; i++)
     63         {
     64             for(int j = 0; j < b.len; j++)
     65             {
     66                 c.s[i+j] += s[i] * b.s[j];
     67             }
     68         }
     69         for(int i = 0; i < c.len; i++)
     70         {
     71             c.s[i+1] += c.s[i]/10;
     72             c.s[i] %= 10;
     73         }
     74         c.clean();
     75         return c;
     76     }
     77     bign operator *= (const bign &b)
     78     {
     79         *this = *this * b;
     80         return *this;
     81     }
     82     bign operator - (const bign &b)
     83     {
     84         bign c;
     85         c.len = 0;
     86         for(int i = 0, g = 0; i < len; i++)
     87         {
     88             int x = s[i] - g;
     89             if(i < b.len) x -= b.s[i];
     90             if(x >= 0) g = 0;
     91             else
     92             {
     93                 g = 1;
     94                 x += 10;
     95             }
     96             c.s[c.len++] = x;
     97         }
     98         c.clean();
     99         return c;
    100     }
    101     bign operator -= (const bign &b)
    102     {
    103         *this = *this - b;
    104         return *this;
    105     }
    106     bign operator / (const bign &b)
    107     {
    108         bign c, f = 0;
    109         for(int i = len-1; i >= 0; i--)
    110         {
    111             f = f*10;
    112             f.s[0] = s[i];
    113             while(f >= b)
    114             {
    115                 f -= b;
    116                 c.s[i]++;
    117             }
    118         }
    119         c.len = len;
    120         c.clean();
    121         return c;
    122     }
    123     bign operator /= (const bign &b)
    124     {
    125         *this  = *this / b;
    126         return *this;
    127     }
    128     bign operator % (const bign &b)
    129     {
    130         bign r = *this / b;
    131         r = *this - r*b;
    132         return r;
    133     }
    134     bign operator %= (const bign &b)
    135     {
    136         *this = *this % b;
    137         return *this;
    138     }
    139     bool operator < (const bign &b)
    140     {
    141         if(len != b.len) return len < b.len;
    142         for(int i = len-1; i >= 0; i--)
    143         {
    144             if(s[i] != b.s[i]) return s[i] < b.s[i];
    145         }
    146         return false;
    147     }
    148     bool operator > (const bign &b)
    149     {
    150         if(len != b.len) return len > b.len;
    151         for(int i = len-1; i >= 0; i--)
    152         {
    153             if(s[i] != b.s[i]) return s[i] > b.s[i];
    154         }
    155         return false;
    156     }
    157     bool operator == (const bign &b)
    158     {
    159         return !(*this > b) && !(*this < b);
    160     }
    161     bool operator != (const bign &b)
    162     {
    163         return !(*this == b);
    164     }
    165     bool operator <= (const bign &b)
    166     {
    167         return *this < b || *this == b;
    168     }
    169     bool operator >= (const bign &b)
    170     {
    171         return *this > b || *this == b;
    172     }
    173     string str() const
    174     {
    175         string res = "";
    176         for(int i = 0; i < len; i++) res = char(s[i]+'0') + res;
    177         return res;
    178     }
    179 };
    180 
    181 istream& operator >> (istream &in, bign &x)
    182 {
    183     string s;
    184     in >> s;
    185     x = s.c_str();
    186     return in;
    187 }
    188 
    189 ostream& operator << (ostream &out, const bign &x)
    190 {
    191     out << x.str();
    192     return out;
    193 }
    194 
    195 bign a,b;
    196 int n;
    197 
    198 int main()
    199 {
    200     scanf("%d",&n);
    201     if (n==1){printf("1"); return 0;}
    202     if (n==2){printf("5"); return 0;}
    203     a=1,b=3;
    204     for (int i=3;i<=n;++i)
    205     {
    206         a=a+b;
    207         swap(a,b);
    208     }
    209     if (n%2==1) b=b*b;
    210     else b=b*b-4;
    211     cout<<b;
    212 }
  • 相关阅读:
    HTML5印章绘制电子签章图片,中文英文椭圆章、中文英文椭圆印章
    送别2019,期待2020!
    [系列] Go
    当查询的数据来自多个数据源,有哪些好的分页策略?
    究竟什么样的开发流程是规范的?
    Git 分支设计规范
    API 接口设计规范
    一线技术管理者究竟在管什么事?
    一个人被提拔,不仅仅是能力,而是信任
    [系列] Go 如何解析 JSON 数据?
  • 原文地址:https://www.cnblogs.com/refun/p/8761331.html
Copyright © 2011-2022 走看看