BZOJ 1002 FJOI2007 轮状病毒 递推+高精度

题目大意:轮状病毒基定义如图。求有多少n轮状病毒

这个递推实在是不会……所以我选择了打表找规律

首先执行下面程序

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define M 110
using namespace std;
struct abcd{
	int to,next;
	bool ban;
}table[M<<2];
int head[M],tot=1;
int n,ans;
void Add(int x,int y)
{
	table[++tot].to=y;
	table[tot].next=head[x];
	head[x]=tot;
}
int fa[M],v[M],q[M],r,h;
bool BFS()
{
	int i;
	r=h=0;
	memset(v,0,sizeof v);
	memset(fa,-1,sizeof fa);
	q[++r]=0;
	while(r!=h)
	{
		int x=q[++h];
		for(i=head[x];i;i=table[i].next)
			if(!table[i].ban)
			{
				if(table[i].to==fa[x])
					continue;
				if(v[table[i].to])
					return 0;
				fa[table[i].to]=x;
				v[table[i].to]=1;
				q[++r]=table[i].to;
			}
	}
	if(r<=n)
		return 0;
	return 1;
}
void DFS(int x)
{
	if(x+x>tot)
	{
		if( BFS() )
			++ans;
		return ;
	}
	table[x<<1].ban=table[x<<1|1].ban=0;
	DFS(x+1);
	table[x<<1].ban=table[x<<1|1].ban=1;
	DFS(x+1);
}
int main()
{
	int i;
	while(1)
	{
		memset(head,0,sizeof head);
		tot=1;ans=0;
		cin>>n;
		for(i=1;i<=n;i++)
			Add(0,i),Add(i,0),Add(i,i%n+1),Add(i%n+1,i);
		DFS(1);
		cout<<ans<<endl;
	}
}

够简单。够暴力吧

然后打表。1~14的答案例如以下

1 5 16 45 121 320 841 2205 5776 15125 39601 103680 271441 710645

奇数项

1 16 121 841 5776 39601 271441

开根号得

1 4 11 29 76 199 521

a[i]=a[i-1]*3-a[i-2]

偶数项

5 45 320 2205 15125 103680 710645

除以5得

1 9 64 441 3025 20736 142129

开根号得

1 3 8 21 55 144 377

a[i]=a[i-1]*3-a[i-2]

然后高精度递推即可了

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
struct abcd{
    int x[100],cnt;
    int& operator [] (int y)
    {
        return x[y];
    }
    void operator = (int y)
    {
        x[1]=y;
        cnt=1;
    }
}f[100];
abcd operator - (abcd x,abcd &y)
{
    int i;
    abcd z=f[0];
    z.cnt=max(x.cnt,y.cnt);
    for(i=1;i<=z.cnt;i++)
    {
        z[i]+=x[i]-y[i];
        if(z[i]<0)
            z[i+1]--,z[i]+=10;
    }
    while(z.cnt&&!z[z.cnt])
        z.cnt--;
    return z;
}
abcd operator * (abcd &x,abcd &y)
{
    int i,j;
    abcd z=f[0];
    for(i=1;i<=x.cnt;i++)
        for(j=1;j<=y.cnt;j++)
            z[i+j-1]+=x[i]*y[j],z[i+j]+=z[i+j-1]/10,z[i+j-1]%=10;
    z.cnt=x.cnt+y.cnt;
    if(!z[z.cnt])
        --z.cnt;
    return z;
}
abcd operator * (abcd x,int y)
{
    int i;
    abcd z=f[0];
    for(i=1;i<=x.cnt;i++)
        z[i]+=x[i]*y,z[i+1]+=z[i]/10,z[i]%=10;
    z.cnt=x.cnt;
    if(z[z.cnt+1])
        ++z.cnt;
    return z;
}
ostream& operator << (ostream &os,abcd x)
{
    int i;
    for(i=x.cnt;i;i--)
        os<<x[i];
    return os;
}
int n;
int main()
{
    int i;
    cin>>n;
    f[1]=1;
    f[2]=n&1?4:3;
    for(i=3;i+i<=n+1;i++)
        f[i]=f[i-1]*3-f[i-2];
    cout<<f[n+1>>1]*f[n+1>>1]*(n&1?1:5)<<endl;
}
时间: 2024-09-30 23:52:00

BZOJ 1002 FJOI2007 轮状病毒 递推+高精度的相关文章

BZOJ 1002: [FJOI2007]轮状病毒 递推/基尔霍夫矩阵树定理

f[n]=3*f[n-1]-f[n-2]+2 1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MB Submit: 2959  Solved: 1644 [Submit][Status][Discuss] Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3 Sample Outpu

bzoj 1002 [FJOI2007]轮状病毒 高精度&amp;&amp;找规律&amp;&amp;基尔霍夫矩阵

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 基尔霍夫矩阵总算编出来了,这道题考

BZOJ 1002 [FJOI2007]轮状病毒

1002: [FJOI2007]轮状病毒 Description 轮状病毒有很多变种,所有轮状病毒的变种都是从一个轮状基产生的.一个N轮状基由圆环上N个不同的基原子和圆心处一个核原子构成的,2个原子之间的边表示这2个原子之间的信息通道.如下图所示 N轮状病毒的产生规律是在一个N轮状基中删去若干条边,使得各原子之间有唯一的信息通道,例如共有16个不同的3轮状病毒,如下图所示 现给定n(N<=100),编程计算有多少个不同的n轮状病毒 Input 第一行有1个正整数n Output 计算出的不同的n

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 name

BZOJ1002 FJOI2007 轮状病毒 递推

题意:给定一个轮状结构(中间一个点,周围有N个点以环状围住这个点),从不相交的2*N-1条边中选N条边,使任意两点间有且只有一条联通路径. 题解:请点这里.然而如果考场上考到直接打表找规律好了 #include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; const int

【递推】【高精度】【FJOI 2007】【bzoj 1002】轮状病毒

1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec Memory Limit: 162 MB Submit: 3238 Solved: 1797 Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3 Sample Output 16 题解: 递推. 打表可以找规律得,f[i]=3*f[i-1]-f[i-2]+2,但是需要高精

BZOJ 1089 严格n元树 (递推+高精度)

题解:用a[i]表<=i时有几种树满足度数要求,那么这样就可以递归了,a[i]=a[i-1]^n+1.n个节点每个有a[i-1]种情况,那么将其相乘,最后加上1,因为深度为0也算一种.那么答案就是a[n]-a[n-1].然后就是高精度的问题了,发现很久没有现码高精度没手感了,连高进度加法进位都出了些问题,需要特别注意. #include <cstdio> #include <cstring> #include <algorithm> using namespace

1002: [FJOI2007]轮状病毒

1002: [FJOI2007]轮状病毒 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 2609  Solved: 1450[Submit][Status] Description 给定n(N<=100),编程计算有多少个不同的n轮状病毒. Input 第一行有1个正整数n. Output 将编程计算出的不同的n轮状病毒数输出 Sample Input 3 Sample Output 16 HINT Source 题解:这道题可以采用“打表—找规律

递推 + 高精度 --- Tiling

Tiling Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7264   Accepted: 3528 Description In how many ways can you tile a 2xn rectangle by 2x1 or 2x2 tiles? Here is a sample tiling of a 2x17 rectangle. Input Input is a sequence of lines,