洛谷P2144 [FJOI2007]轮状病毒

题目描述

轮状病毒有很多变种。许多轮状病毒都是由一个轮状基产生。一个n轮状基由圆环上n个不同的基原子和圆心的一个核原子构成。2个原子之间的边表示这2个原子之间的信息通道,如图1。

n轮状病毒的产生规律是在n轮状基中删除若干边,使各原子之间有唯一一条信息通道。例如,共有16个不同的3轮状病毒,入图2所示。

给定n(N<=100),编程计算有多少个不同的n轮状病毒。

这里写图片描述

输入输出格式

输入格式:
第一行有1个正整数n。

输出格式:
将编程计算出的不同的n轮状病毒数输出

输入输出样例

输入样例#1:
3
输出样例#1:
16

【题解】

做这题颇有感触啊,感觉省选题目画半个小时画图不吃亏。

看到题目,反正我的第一反应是递推。递推就要有递推式,于是我花了将近20分钟,画出n=1~5情况的轮状病毒个数:

1 5 16 45 121……

乍一看,奇数项是完全平方数,偶数项是5的倍数,我想的是往平方数上靠,于是转化成了这样:

1*1 3*3-4 4*4 7*7-4 11*11……

1 3 4 7 11……

就是这样,原来是个变形的Fibonacci数列,前两项为1和3,然后对每一项平方,如果是偶数项就减4,AC~

递推式:F[n]=f[n]f[n]-4(n+1 mod 2),f[n]=f[n-1]+f[n-2],f[1]=1,f[2]=3

然后难点就在于高精度了。(这玩意我搞了一个半小时。。。)

对于高精度,我喜欢用刘汝佳《算法竞赛入门经典》上的大整数类,这种方法就是定义一个class,通过符号重载,让打高精度运算和打普通运算一样简单。这样就不用专为每道题打专门的高精度,需要时在程序前套板子即可。(但这样似乎加大了代码量)

随代码附上高精度模板:

#include<iostream>
#include<cmath>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#define fp(i,a,b) for(int i=a;i<=b;i++)
#define fq(i,a,b) for(int i=a;i>=b;i--)
#define il inline
#define re register
#define ll long long 
using namespace std;
const int maxN=100001;
const int inf=2147483647;
class BigInteger { public:

int size,num[1000];//size代表数的长度,num存大整型数

    BigInteger()//定义时自动清零
        {
            size=0;
            memset(num,0,sizeof(num));
        }
    BigInteger(int data)
        {
            size=0;
            while (data!=0)
            {
                size++;
                num[size]=data%10;
                data=data/10;
            }
        }
    void init(int data)//用来给大整型变量赋整型值
        {
            size=0;
            while (data!=0)
            {
                size++;
                num[size]=data%10;
                data=data/10;
            }
        }
};
BigInteger operator + (BigInteger A,BigInteger B)//高精度加法
{
    BigInteger Ans;
    int s=max(A.size,B.size);
    Ans.size=s;
    for (int i=1;i<=s;i++)
        Ans.num[i]=A.num[i]+B.num[i];
    for (int i=1;i<=s;i++)
        if (Ans.num[i]>=10)
        {
            Ans.num[i+1]+=Ans.num[i]/10;
            Ans.num[i]=Ans.num[i]%10;
        }
    if (Ans.num[s+1]!=0)
        Ans.size++;
    return Ans;
}
BigInteger operator - (BigInteger A,BigInteger B)//高精度减法
{
    BigInteger Ans;
    int s=max(A.size,B.size);
    Ans.size=s;
    for (int i=1;i<=s;i++)
        Ans.num[i]=A.num[i]-B.num[i];
    for (int i=1;i<=s;i++)
        if (Ans.num[i]<0)
        {
            Ans.num[i+1]-=Ans.num[i]/10;
            Ans.num[i]=Ans.num[i]%10;
        }
    if (Ans.num[s+1]!=0)
        Ans.size++;
    return Ans;
}
ostream & operator << (ostream &os,BigInteger A)//用于大整型数的输出(只能用cout)
{
    int s=A.size;
    for (int i=s;i>=1;i--)
        os<<A.num[i];
    return os;
}
BigInteger operator * (BigInteger A,BigInteger B)//高精度乘法
{
    BigInteger Ans;
    int s1=A.size,s2=B.size;
    for (int i=1;i<=s1;i++)
        for (int j=1;j<=s2;j++)
            Ans.num[i+j-1]+=A.num[i]*B.num[j];
    int s=s1+s2-1;
    int k=1;
    while ((Ans.num[k]!=0)||(k<=s))
    {
        Ans.num[k+1]+=Ans.num[k]/10;
        Ans.num[k]=Ans.num[k]%10;
        k++;
    }
    if (Ans.num[k]==0)
        k--;
    Ans.size=k;
    return Ans;
}
BigInteger Ans,Ans1,Ans2;//定义大整型数
il int gi()
{
   int x=0;
   short int t=1;
   char ch=getchar();
  while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
  if(ch=='-') t=-1,ch=getchar();
  while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  return x*t;
}
int main()
{
    Ans1.init(1);//把Ans1赋值为1,不能写Ans1=1!!!
    Ans2.init(3);//把Ans2赋值为3,不能写Ans2=3!!!
    int n=gi();
    for(int i=3;i<=n;i++) if(i%2) Ans1=Ans1+Ans2;
        else Ans2=Ans2+Ans1;
    if(n%2) Ans=Ans1;
    else Ans=Ans2;//求f[n]
    if(n%2) Ans=Ans*Ans;
    else Ans=Ans*Ans-4;//求F[n]
    cout<<Ans<<endl;
    return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自动控制节水灌溉技术的高低代表着农业现代化的发展状况,灌溉系统自动化水平较低是制约我国高效农业发展的主要原因。本文就此问题研究了单片机控制的滴灌节水灌溉系统,该系统可对不同土壤的湿度进行监控,并按照作物对土壤湿度的要求进行适时、适量灌水,其核心是单片机和PC机构成的控制部分,主要对土壤湿度与灌水量之间的关系、灌溉控制技术及设备系统的硬件、软件编程各个部分进行了深入的研究。 单片机控制部分采用上下位机的形式。下位机硬件部分选用AT89C51单片机为核心,主要由土壤湿度传感器,信号处理电路,显示电路,输出控制电路,故障报警电路等组成,软件选用汇编语言编程。上位机选用586型以上PC机,通过MAX232芯片实现同下位机的电平转换功能,上下位机之间通过串行通信方式进行数据的双向传输,软件选用VB高级编程语言以建立友好的人机界面。系统主要具有以下功能:可在PC机提供的人机对话界面上设置作物要求的土壤湿度相关参数;单片机可将土壤湿度传感器检测到的土壤湿度模拟量转换成数字量,显示于LED显示器上,同时单片机可采用串行通信方式将此湿度值传输到PC机上;PC机通过其内设程序计算出所需的灌水量和灌水时间,且显示于界面上,并将有关的灌水信息反馈给单片机,若需灌水,则单片机系统启动鸣音报警,发出灌水信号,并经放大驱动设备,开启电磁阀进行倒计时定时灌水,若不需灌水,即PC机上显示的灌水量和灌水时间均为0,系统不进行灌水。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值