1002. [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

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

  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 }

原文地址:https://www.cnblogs.com/refun/p/8761331.html

时间: 2024-10-08 05:34:19

1002. [FJOI2007]轮状病毒【找规律+递推】的相关文章

51nod 1350 斐波那契表示 (找规律递推)

分析: - -! 找规律...首先可以归纳证明,对于n,最佳的取法是先取不大于n的最大的那个斐波那契数,然后递推.从而可以得到算出F(n)的一个方法,但是n的范围太大了,先算出n较小的情况,会发现: 第三列为F(n),第二列为G(n),可以看出第k块是由k-1块和k-2块+1合在一起得到的,从而可以先预处理前k块之和(k不会超过100),然后对于每个n,先找到最大的不超过n的那块,然后对剩下的项递归,总的复杂度为O(T*logn). 1 #include<iostream> 2 #includ

2018南京区域赛G题 Pyramid——找规律&amp;&amp;递推

先手动推出前10项,再上BM板子求出递推式 $A_n = 5A_{n-1} - 10A_{n-2} + 10A_{n-3} - 5A_{n-4} + A_{n-5}$,根据特征根理论可求出特征方程 $(x-1)^5$,设 $A_n = k_1n^4 + k_2n^3 + k_3n^2+k_4n+k_5$,代入前5项求出系数(用了高斯消元法解方程组). 这样虽然做出来了,但是感觉比较浪费时间,因为BM板子和高斯消元法的板子都不短,对手残狗不友好. 差分 首先前7项分别为1  5 15 35 70

[bzoj1002][FJOI2007 轮状病毒] (生成树计数+递推+高精度)

Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图所示 N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不同的3轮状病毒,如下图所示 现给定n(N<=100),编程计算有多少个不同的n轮状病毒 Input 第一行有1个正整数n Output 计算出的不同的n轮状病毒数输出 Sample Input

踩方格(找规律 递推)

踩方格 时间限制: 1 Sec  内存限制: 128 MB提交: 8  解决: 7[提交][状态][讨论版][命题人:quanxing] 题目描述 有一个方格矩阵,矩阵边界在无穷远处.我们做如下假设: a.每走一步时,只能从当前方格移动一格,走到某个相邻的方格上: b.走过的格子立即塌陷无法再走第二次: c.只能向北.东.西三个方向走: 请问:如果允许在方格矩阵上走n步,共有多少种不同的方案.2种走法只要有一步不一样,即被认为是不同的方案. 输入 允许在方格上行走的步数n(n≤20). 输出 计

bzoj 1002 [FJOI2007]轮状病毒 高精度&amp;&amp;找规律&amp;&amp;基尔霍夫矩阵

1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2234  Solved: 1227[Submit][Status] Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3 Sample Output 16 HINT Source 基尔霍夫矩阵总算编出来了,这道题考

BZOJ 1002: [FJOI2007]轮状病毒 递推/基尔霍夫矩阵树定理

f[n]=3*f[n-1]-f[n-2]+2 1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 2959  Solved: 1644 [Submit][Status][Discuss] Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3 Sample Outpu

1002: [FJOI2007]轮状病毒

1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2609  Solved: 1450[Submit][Status] Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3 Sample Output 16 HINT Source 题解:这道题可以采用“打表—找规律

BZOJ 1002 [FJOI2007]轮状病毒

1002: [FJOI2007]轮状病毒 Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图所示 N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不同的3轮状病毒,如下图所示 现给定n(N<=100),编程计算有多少个不同的n轮状病毒 Input 第一行有1个正整数n Output 计算出的不同的n

BZOJ 1002 FJOI2007 轮状病毒 递推+高精度

题目大意:轮状病毒基定义如图.求有多少n轮状病毒 这个递推实在是不会--所以我选择了打表找规律 首先执行下面程序 #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define M 110 using namespace std; struct abcd{ int to,next; bool ban; }table[M<<2]; int head[