1002: [FJOI2007]轮状病毒
Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 2234 Solved: 1227
[Submit][Status]
Description
给定n(N<=100),编程计算有多少个不同的n轮状病毒。
Input
第一行有1个正整数n。
Output
将编程计算出的不同的n轮状病毒数输出
Sample Input
3
Sample Output
16
HINT
Source
基尔霍夫矩阵总算编出来了,这道题考察的就是数列找规律,要善于联系斐波那契等数列,完全平方数列,奇偶项分别探究。
另外,终于知道c++中四射五入时roundf(float) round(double) roundl(long double)
这道题真在考场上估计是想不出来,主要是因为数列前两项与基尔霍夫矩阵求出的不同,就老是有求错的心理压力。
高精度模板有较小的改动
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<vector>
using namespace std;
#define eps 1e-7
#define MAXN 111
#ifdef unix120G
#define LL "%lld"
#else
#define LL "%I64d"
#endif
/*
1
5=5*1*1
16=4*4
45=5*3*3
121=11*11
320=5*8*8
841=29*29
2205=5*21*21
5776=76*76
15125
39601
103680
271441
710645
1860496
4870845
12752041
*/
typedef long double real;
typedef long long qword;
int n,m,mod;
int a[MAXN][MAXN];
typedef int arr_t[MAXN][MAXN];
real b[MAXN][MAXN];
void pm()
{
int i,j;
cout<<endl;
for (i=;i<n;i++)
{
for (j=;j<n;j++)
{
cout<<b[i][j]<<"\t";
}
cout<<endl;
}
cout<<endl;
return ;
}
int gauss(arr_t a,int n)
{
int i,j,k,sign,x;
for (i=;i<n;i++)
{
for (j=;j<n;j++)
{
b[i][j]=a[i][j];
}
}
real temp,ans=;
for (i=;i<n;i++)
{
if (abs(b[i][i])<eps)
{
for (j=i+;j<n;j++)
{
if (abs(b[j][i])>eps)
break;
}
if (j==n)return ;
x=j;
for (j=;j<n;j++)
{
swap(b[x][j],b[i][j]);
}
}
ans*=b[i][i];
for (j=i+;j<n;j++)
{
b[i][j]/=b[i][i];
}
for (j=i+;j<n;j++)
{
for (k=i+;k<n;k++)
{
b[j][k]-=b[i][k]*b[j][i];
}
}
// pm();
}
return (int)roundl(ans);
} qword work1()
{
int i,j,k;
memset(a,,sizeof(a));
for (i=;i<n;i++)
{
a[i][(i+)%n]=a[(i+)%n][i]=-;
a[n][i]=a[i][n]=-;
}
for (i=;i<n;i++)a[i][i]=;
a[n][n]=n;
cout<<gauss(a,n)<<endl;;
}
#define MAXL 10000
#define VAL1 10000
class number//四位
{
public:
number()
{
clear();
}
bool is_odd()
{
return numb[]%==;
}
bool is_even()
{
return numb[]%==;
}
void lsh_bin()
{
int i;
for (i=topn;i>;i--)
{
if (numb[i]%==)
{
numb[i-]+=VAL1;
}
numb[i]/=;
}
numb[]/=;
while (topn&&!numb[topn])topn--;
}
bool equal_to(int x)
{
if (topn==)
{
return x==numb[];
}
if (topn==)
{
return x==numb[]+numb[]*VAL1;
}
return false;
}
int size()
{
return topn;
}
int length()
{
int x=numb[topn];
int ret=;
while (x)
{
ret++;
x/=;
}
int y=;
x=VAL1;
while (x)
{
y++;
x/=;
}
y--;
ret+=topn*y;
return ret;
}
void operator =(int x)//{{{
{
int now=;
clear();
numb[now]=x;
while (numb[now]>=VAL1)
{
numb[now+]+=numb[now]/VAL1;
numb[now]%=VAL1;
now++;
if (now>topn)topn=now;
}
}//}}}
void operator =(number num)//{{{
{
topn=num.topn;
memcpy((this->numb),num.numb,sizeof(num.numb[])*(topn+));
}//}}}
void operator +=(number &num)//{{{
{
int i;
topn=max(topn,num.topn);
for (i=;i<=topn;i++)
{
numb[i]+=num.numb[i];;
if (numb[i]>=VAL1)
{
numb[i+]+=numb[i]/VAL1;
numb[i]%=VAL1;
}
}
while (numb[topn+])
{
topn++;
numb[topn+]+=numb[topn]/VAL1;
numb[topn]%=VAL1;
}
}//}}}
void operator +=(int x)//{{{
{
int now=;
if (topn==-)topn=;
numb[now]+=x;
while (numb[now]>=VAL1)
{
numb[now+]+=numb[now]/VAL1;
numb[now]%=VAL1;
now++;
if (now>topn)topn=now;
}
}//}}}
void operator *=(int x)//{{{
{
int i;
for (i=;i<=topn;i++)
{
numb[i]*=x;
}
for (i=;i<=topn;i++)
{
if (numb[i]>=VAL1)
{
numb[i+]+=numb[i]/VAL1;
numb[i]%=VAL1;
}
}
while (numb[topn+])
{
topn++;
numb[topn+]+=numb[topn]/VAL1;
numb[topn]%=VAL1;
}
}//}}}
void operator -=(number &num)//{{{
{
if (*this<num)throw "Error!\n->void operator -=(number &num)\n";
int i;
for (i=;i<=topn;i++)
{
numb[i]-=num.numb[i];
}
for (i=;i<=topn;i++)
{
while (numb[i]<)
{
numb[i]+=VAL1;
numb[i+]--;
}
}
while (topn&&!numb[topn])topn--;
}//}}}
void operator --(int)//{{{
{
if (topn==&&numb[]==)throw "Error!\n->void operator --(int)\n";
int now=;
numb[now]--;
while (numb[now]<)
{
numb[now+]--;
numb[now]+=VAL1;
}
while (topn&&!numb[topn])topn--;
}//}}}
private:
int numb[MAXL];
int topn;
void clear()
{
topn=;
memset(numb,,sizeof(numb)); }
friend bool operator <(number num1,number num2);
friend bool operator <=(number num1,number num2);
friend bool operator ==(number num1,number num2);
friend ostream& operator <<(ostream &out,number &num);
friend istream& operator >>(istream &in,number &num);
friend number operator *(number &num1,number &num2);
friend number operator *(number num,int x);
friend number operator +(number num1,number num2);
friend number operator +(number num1,int x);
friend number operator -(number num1,number num2);
//a=a+b远没有a+=b快
};
bool operator <(number num1,number num2)//{{{
{
if (num1.topn!=num2.topn)
{
return num1.topn<num2.topn;
}
int i;
for (i=num1.topn;i>=;i--)
{
if (num1.numb[i]!=num2.numb[i])
{
return num1.numb[i]<num2.numb[i];
}
}
return false;
}//}}}
bool operator <=(number num1,number num2)//{{{
{
if (num1.topn!=num2.topn)
{
return num1.topn<num2.topn;
}
int i;
for (i=num1.topn;i>=;i--)
{
if (num1.numb[i]!=num2.numb[i])
{
return num1.numb[i]<num2.numb[i];
}
}
return true;
}//}}}
bool operator ==(number num1,number num2)//{{{
{
if (num1.topn!=num2.topn)return false;
for (int i=;i<=num1.topn;i++)
{
if (num1.numb[i]!=num2.numb[i])return false;
}
return true;
}//}}}
ostream& operator <<(ostream &out,number &num)//{{{
{
int i;
out<<num.numb[num.topn];
for (i=num.topn-;i>=;i--)
{
//压六位时
// if (num.numb[i]<100000)out<<"0";
// if (num.numb[i]<10000)out<<"0";
if (num.numb[i]<)out<<"";
if (num.numb[i]<)out<<"";
if (num.numb[i]<)out<<"";
out<<num.numb[i];
}
return out;
}//}}}
istream& operator >>(istream &in,number &num)//{{{
{
string str;
in>>str;
int i;
num.clear();
for (i=(int)str.length()-,num.topn=;i>=;i-=,num.topn++)
{
if (i-<str.length())
{
num.numb[num.topn]=(str[i]-'')+*(str[i-]-'')+*(str[i-]-'')+*(str[i-]-'');
}else
{
if (i-<str.length())num.numb[num.topn]+=*(str[i-]-'');
if (i-<str.length())num.numb[num.topn]+=*(str[i-]-'');
if (i <str.length())num.numb[num.topn]+=(str[i]-'');
}
}
num.topn--;
return in;
}//}}}
number operator *(number num,int x)//{{{
{
number ret;
ret=num;
ret*=x;
return ret;
}//}}}
number operator +(number num1,number num2)//{{{
{
number ret;
ret=num1;
ret+=num2;
return ret;
}//}}}
number operator +(number num1,int x)//{{{
{
number ret;
ret=num1;
ret+=x;
return ret;
}//}}}
number operator -(number num1,number num2)//{{{
{
number ret;
ret=num1;
ret-=num2;
return ret;
}//}}
number f[];
int main()
{
freopen("input.txt","r",stdin);
//freopen(PROB".out","w",stdout);
int x,y;
int i,j,k;
scanf("%d",&n);
if (n==)
{
printf("1\n");
return ;
}
if (n==)
{
printf("5\n");
return ;
}
f[]=;f[]=;
for (i=;i<=n;i++)
f[i]=f[i-]*-f[i-]+;
//for (i=1;i<=n;i++)cout<<f[i]<<endl;
cout<<f[n]<<endl;
return ;
}