1. 程式人生 > >bzoj 1002 [FJOI2007]輪狀病毒——打表找規律

bzoj 1002 [FJOI2007]輪狀病毒——打表找規律

題目:https://www.lydsy.com/JudgeOnline/problem.php?id=1002

看 Zinn 的部落格:https://www.cnblogs.com/Zinn/p/9252831.html

時隔六個月,自己終於也 A 了這道題。

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define db double
using namespace std;
const int N=105;
int n;db a[N][N];
db 
get() { db ret=1; for(int i=1;i<=n;i++) { for(int j=i+1;j<=n;j++) if(fabs(a[j][i])>fabs(a[i][i])) { for(int t=i;t<=n;t++)swap(a[i][t],a[j][t]); } if(!a[i][i])return 0; for(int j=i+1;j<=n;j++) { db sl=a[j][i]/a[i][i]; for(int
t=i;t<=n;t++)a[j][t]-=sl*a[i][t]; } ret*=a[i][i]; } return ret; } int main() { int lm;scanf("%d",&lm); for(n=3;n<=lm;n++) { for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)a[i][j]=0; for(int i=1;i<=n;i++) { a[i][i]+=3; i==1?a[i][n]-=1:a[i][i-1
]-=1; i==n?a[i][1]-=1:a[i][i+1]-=1; a[i][n+1]-=1;a[n+1][i]-=1; } a[n+1][n+1]+=n; printf("%.0f ",get()); } puts(""); return 0; }
打表

精度誤差真的很大。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=105,base=1e8;
int n,a[N][N];
void mul(int *a,int *ret,int b)
{
  ret[0]=a[0];
  for(int i=1;i<=a[0];i++)
    ret[i]=a[i]*b;
  for(int i=1;i<=ret[0];i++)
    ret[i+1]+=ret[i]/base,ret[i]%=base;
  while(ret[ret[0]+1])ret[0]++,ret[ret[0]+1]+=ret[ret[0]]/base,ret[ret[0]]%=base;
}
void dec(int *a,int *b)
{
  for(int i=1;i<=a[0];i++)
    {
      a[i]-=b[i];
      if(a[i]<0)a[i]+=base,a[i+1]--;
    }
  while(a[0]&&!a[a[0]])a[0]--;
}
void add(int *a,int b)
{
  a[1]+=b;
  for(int i=1;i<=a[0]&&a[i]>=base;i++)
    a[i+1]++,a[i]-=base;
  if(a[a[0]+1])a[0]++;
}
void print(int *a)
{
  printf("%d",a[a[0]]);
  for(int i=a[0]-1;i;i--)printf("%08d",a[i]);puts("");
}
int main()
{
  scanf("%d",&n);
  if(n<=2){puts("1");return 0;}
  a[3][0]=1;a[3][1]=16;a[4][0]=1;a[4][1]=45;
  if(n<=4){printf("%d\n",a[n][1]);return 0;}
  for(int i=5;i<=n;i++)
    {
      mul(a[i-1],a[i],3);
      dec(a[i],a[i-2]);add(a[i],2);
    }
  print(a[n]);return 0;
}