bzoj 1002 [FJOI2007]轮状病毒——打表找规律

Posted narh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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
",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;
}

 

以上是关于bzoj 1002 [FJOI2007]轮状病毒——打表找规律的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ 1002 FJOI2007 轮状病毒

BZOJ 1002: [FJOI2007]轮状病毒

BZOJ 1002: [FJOI2007]轮状病毒

BZOJ 1002 [FJOI2007]轮状病毒

BZOJ1002: [FJOI2007]轮状病毒

BZOJ 1002: [FJOI2007]轮状病毒