bzoj 1002 [FJOI2007]轮状病毒 高精度&&找规律&&基尔霍夫矩阵
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
基尔霍夫矩阵总算编出来了,这道题考察的就是数列找规律,要善于联系斐波那契等数列,完全平方数列,奇偶项分别探究。
另外,终于知道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=0;i<n;i++) { for (j=0;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=0;i<n;i++) { for (j=0;j<n;j++) { b[i][j]=a[i][j]; } } real temp,ans=1; for (i=0;i<n;i++) { if (abs(b[i][i])<eps) { for (j=i+1;j<n;j++) { if (abs(b[j][i])>eps) break; } if (j==n)return 0; x=j; for (j=0;j<n;j++) { swap(b[x][j],b[i][j]); } } ans*=b[i][i]; for (j=i+1;j<n;j++) { b[i][j]/=b[i][i]; } for (j=i+1;j<n;j++) { for (k=i+1;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,0,sizeof(a)); for (i=0;i<n;i++) { a[i][(i+1)%n]=a[(i+1)%n][i]=-1; a[n][i]=a[i][n]=-1; } for (i=0;i<n;i++)a[i][i]=3; 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[0]%2==1; } bool is_even() { return numb[0]%2==0; } void lsh_bin() { int i; for (i=topn;i>0;i--) { if (numb[i]%2==1) { numb[i-1]+=VAL1; } numb[i]/=2; } numb[0]/=2; while (topn&&!numb[topn])topn--; } bool equal_to(int x) { if (topn==0) { return x==numb[0]; } if (topn==1) { return x==numb[0]+numb[1]*VAL1; } return false; } int size() { return topn; } int length() { int x=numb[topn]; int ret=0; while (x) { ret++; x/=10; } int y=0; x=VAL1; while (x) { y++; x/=10; } y--; ret+=topn*y; return ret; } void operator =(int x)//{{{ { int now=0; clear(); numb[now]=x; while (numb[now]>=VAL1) { numb[now+1]+=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[0])*(topn+1)); }//}}} void operator +=(number &num)//{{{ { int i; topn=max(topn,num.topn); for (i=0;i<=topn;i++) { numb[i]+=num.numb[i];; if (numb[i]>=VAL1) { numb[i+1]+=numb[i]/VAL1; numb[i]%=VAL1; } } while (numb[topn+1]) { topn++; numb[topn+1]+=numb[topn]/VAL1; numb[topn]%=VAL1; } }//}}} void operator +=(int x)//{{{ { int now=0; if (topn==-1)topn=0; numb[now]+=x; while (numb[now]>=VAL1) { numb[now+1]+=numb[now]/VAL1; numb[now]%=VAL1; now++; if (now>topn)topn=now; } }//}}} void operator *=(int x)//{{{ { int i; for (i=0;i<=topn;i++) { numb[i]*=x; } for (i=0;i<=topn;i++) { if (numb[i]>=VAL1) { numb[i+1]+=numb[i]/VAL1; numb[i]%=VAL1; } } while (numb[topn+1]) { topn++; numb[topn+1]+=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=0;i<=topn;i++) { numb[i]-=num.numb[i]; } for (i=0;i<=topn;i++) { while (numb[i]<0) { numb[i]+=VAL1; numb[i+1]--; } } while (topn&&!numb[topn])topn--; }//}}} void operator --(int)//{{{ { if (topn==0&&numb[0]==0)throw "Error!\n->void operator --(int)\n"; int now=0; numb[now]--; while (numb[now]<0) { numb[now+1]--; numb[now]+=VAL1; } while (topn&&!numb[topn])topn--; }//}}} private: int numb[MAXL]; int topn; void clear() { topn=0; memset(numb,0,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>=0;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>=0;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=0;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-1;i>=0;i--) { //压六位时 // if (num.numb[i]<100000)out<<"0"; // if (num.numb[i]<10000)out<<"0"; if (num.numb[i]<1000)out<<"0"; if (num.numb[i]<100)out<<"0"; if (num.numb[i]<10)out<<"0"; 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()-1,num.topn=0;i>=0;i-=4,num.topn++) { if (i-3<str.length()) { num.numb[num.topn]=(str[i]-'0')+10*(str[i-1]-'0')+100*(str[i-2]-'0')+1000*(str[i-3]-'0'); }else { if (i-2<str.length())num.numb[num.topn]+=100*(str[i-2]-'0'); if (i-1<str.length())num.numb[num.topn]+=10*(str[i-1]-'0'); if (i <str.length())num.numb[num.topn]+=(str[i]-'0'); } } 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[101]; int main() { freopen("input.txt","r",stdin); //freopen(PROB".out","w",stdout); int x,y; int i,j,k; scanf("%d",&n); if (n==1) { printf("1\n"); return 0; } if (n==2) { printf("5\n"); return 0; } f[1]=1;f[2]=5; for (i=3;i<=n;i++) f[i]=f[i-1]*3-f[i-2]+2; //for (i=1;i<=n;i++)cout<<f[i]<<endl; cout<<f[n]<<endl; return 0; }
by mhy12345(http://www.cnblogs.com/mhy12345/) 未经允许请勿转载
本博客已停用,新博客地址:http://mhy12345.xyz