1002: [FJOI2007]轮状病毒
Time Limit: 1 Sec Memory Limit: 162 MB[ Submit][ Status]
Description
给定n(N<=100),编程计算有多少个不同的n轮状病毒。
Input
第一行有1个正整数n。
Output
将编程计算出的不同的n轮状病毒数输出
Sample Input
3
Sample Output
16
第一眼看上去,n<=100
不错 打表 于是就写了一个暴力搜索
可是说好的暴力出奇迹呢?
跑了半天就跑到了18
我就呵呵呵了
恩!
开始找规律 !我就笑笑不说话
好了!我不会告诉你
a[n]=a[n-1]*3-a[n-2]+2;
//反正我是没搞出来的
好了先看看,暴力出奇迹
暴力代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=200;
struct node
{
int l,r;
}map[maxn];
int f[maxn],N,n,i,ans;
bool flag[maxn];
int find(int x)
{
if (x==f[x]) return x;
return f[x]=find(f[x]);
}
void search(int k,int sta)
{
if (k==n+1)
{
ans++;
return;
}
int temp[maxn];
for (int i=sta+1;i<=N;i++)
if (!flag[i])
{
int t1=find(map[i].l);
int t2=find(map[i].r);
if (t1==t2) continue;
for (int j=0;j<=n;j++)
temp[j]=f[j];
flag[i]=true;f[t1]=t2;
search(k+1,i);
for (int j=0;j<=n;j++)
f[j]=temp[j];
flag[i]=false;
}
}
int main()
{
for(n=1;n<=100;n++)
{
for(i=1;i<n;i++)
{
map[i].l=i;
map[i].r=i+1;
}
map[n].l=n;
map[n].r=1;
for(i=n+1;i<=n+n;i++)
{
map[i].l=0;
map[i].r=i-n;
}
N=2*n;
for(i=0;i<=n;i++)
f[i]=i;
search(1,0);
printf("%d——>%d\n",n,ans);
ans=0;
}
return 0;
}
AC代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
//a[n] = 3 * a[n-1] - a[n-2] + 2
const int base=10000;
struct bign
{
int len,c[10000],sign;
bign()
{
memset(c,0,sizeof(c));
len=1;
sign=0;
}
void zero()
{
while(len>1&&c[len]==0)len--;
}
void writein(char *s)
{
int l=strlen(s),k=1;
for(int i=l-1;i>=0;i--)
{
c[len]+=(s[i]-'0')*k;
k*=10;
if(k==base)
{
k=1;
len++;
}
}
zero();
}
void read()
{
char s[10000];
scanf("%s",s);
writein(s);
}
bign operator = (int b)
{
char s[10000];
sprintf(s,"%d",b);
writein(s);
return *this;
}
void print()//输出
{
if(sign)printf("-");
printf("%d",c[len]);
for(int i=len-1;i>=1;i--)
printf("%04d",c[i]);
//printf("\n");
}
bool operator < (const bign &b)const
{
if(len!=b.len)return len<b.len;
for(int i=len;i>=1;i--)
if(c[i]!=b.c[i])return c[i]<b.c[i];
return 0;
}
bign operator + (const bign &b)const
{
bign x;
x.len=max(len,b.len)+1;
for(int i=1;i<=x.len;i++)
{
x.c[i]+=c[i]+b.c[i];
x.c[i+1]+=x.c[i]/base;
x.c[i]%=base;
}
x.zero();
return x;
}
bign operator + (const int &b)const
{
bign x;
x=b;
return *this + x;
}
bign operator - (const bign &c)const// 高精-高精
{
bign x;
bign a=*this,b=c;
if(a<b)
{
x.sign=1;
swap(a,b);
}
x.len=a.len;
for(int i=1;i<=a.len;i++)
{
x.c[i]=a.c[i]-c.c[i];
if(x.c[i]<0)
{
x.c[i]+=base;
a.c[i+1]--;
}
}
x.zero();
return x;
}
bign operator * (const bign &b)const
{
bign x;
x.len=len+b.len;
for(int i=1;i<=len;i++)
for(int j=1;j<=b.len;j++)
{
x.c[i+j-1]+=c[i]*b.c[j];
x.c[i+j]+=x.c[i+j-1]/base;
x.c[i+j-1]%=base;
}
x.zero();
return x;
}
bign operator * (const int &b)const
{
bign x;
x=b;
return *this * x;
}
}a[110];
int n;
int main()
{
a[1]=1;
a[2]=5;
cin>>n;
for(int i=3;i<=n;i++)
{
a[i]=a[i-1]*3-a[i-2]+2;
}
a[n].print();
return 0;
}