九连环是一种源于中国的传统智力游戏。如图所示,九个圆环套在一把“剑”上,并且互相牵连。游戏的目标是把九个圆环从“剑”上卸下。
圆环的装卸需要遵守两个规则。
第一个(最右边)环任何时候都可以装上或卸下。
如果第k个环没有被卸下,且第k个环右边的所有环都被卸下,则第k+1个环(第k个环左边相邻的环)可以任意装上或卸下。
与魔方的千变万化不同,解九连环的最优策略是唯一的。为简单起见,我们以“四连环”为例,演示这一过程。这里用1表示环在“剑”上,0表示环已经卸下。
初始状态为1111,每部的操作如下:
1101(根据规则2,卸下第2个环)
1100(根据规则1,卸下第1个环)
0100(根据规则2,卸下第4个环)
0101(根据规则1,装上第1个环)
0111(根据规则2,装上第2个环)
0110(根据规则1,卸下第1个环)
0010(根据规则2,卸下第3个环)
0011(根据规则1,装上第1个环)
0001(根据规则2,卸下第2个环)
0000(根据规则1,卸下第1个环)
由此可见,卸下“四连环”至少需要10步。随着环数增加,需要的步数也会随之增多。例如卸下九连环,就至少需要341步。
请你计算,有n个环的情况下,按照规则,全部卸下至少需要多少步。
输入
输入第一行为一个整数m ,表示测试点数目。
接下来m行,每行一个整数n。
输出
输出共m行,对应每个测试点的计算结果。
分析:
写出规律:
规律:
奇数 : a[i]= a[i-1]*2+1; 偶数:a[i]=a[i-1]*2; 因为数值已经爆long long 型,所以可以使用java 大数直接调用java的函数来写,也可以c++大整数类的相关运算 来解决,也可以c 语言手动模拟四则运算来写。
1.java大数:
import java.util.*;
import java.math.*;
public class dashu{
public static void main(String[] args) {
int m,n;
Scanner cin=new Scanner(System.in);
m=cin.nextInt();
while(m>0) {
m--;
n=cin.nextInt();
if(n==1)
System.out.println("1");
else
{
BigInteger s;
BigInteger a=BigInteger.valueOf(1);
BigInteger b=BigInteger.valueOf(2);
s=a;
for(int i=2;i<=n;i++)
{
if(i%2==0)
s=s.multiply(b);
else{
s=s.multiply(b);
s=s.add(a);
}
}
System.out.println(s);
}
}
}
}
2.c++使用大整数类的模板来写(重载运算符)这种做法,还未进行理解,等会再看
#include<bits/stdc++.h>
using namespace std;
const int ten[4]= {1,10,100,1000};
const int max1=10000;
struct BigNumber
{
int d[max1];
BigNumber (string s)
{
int len=s.size();
d[0]=(len-1)/4+1;
int i,j,k;
for(i=1; i<max1; i++)
d[i]=0;
for(i=len-1; i>=0; i--)
{
j=(len-i-1)/4+1;
k=(len-i-1)%4;
d[j]+=ten[k]*(s[i]-'0');
}
while(d[0]>1&&d[d[0]]==0)
--d[0];
}
BigNumber(){
*this=BigNumber(string("0"));
}
string toString(){
string s("");
int i,j,temp;
for(i=3; i>=1; i--)
if(d[d[0]]>=ten[i])
break;
temp=d[d[0]];
for(int j=i; j>=0; j--){
s=s+(char)(temp/ten[j]+'0');
temp%=ten[j];
}
for(i=d[0]-1; i>0; i--){
temp=d[i];
for(int j=3; j>=0; j--){
s=s+(char)(temp/ten[j]+'0');
temp%=ten[j];
}
}
return s;
}
} zero("0"),one("1"),two("2"),three("3"),mid1[2000],d,temp;
BigNumber operator +(const BigNumber &a,const BigNumber &b)
{
BigNumber c;
c.d[0]=max(a.d[0],b.d[0]);
int i,x=0;
for(i=1; i<=c.d[0]; ++i){
x=a.d[i]+b.d[i]+x;
c.d[i]=x%10000;
x/=10000;
}
while(x!=0){
c.d[++c.d[0]]=x%10000;
x/=10000;
}
return c;
}
BigNumber operator *(const BigNumber &a,const BigNumber &b)
{
BigNumber c;
c.d[0]=a.d[0]+b.d[0];
int i,j,x;
for(i=1; i<=a.d[0]; i++){
x=0;
for(j=1; j<=b.d[0]; j++){
x=a.d[i]*b.d[j]+x+c.d[i+j-1];
c.d[i+j-1]=x%10000;
x/=10000;
}
c.d[i+b.d[0]]=x;
}
while( (c.d[0]>1) && (c.d[c.d[0]]==0) )
--c.d[0];
return c;
}
BigNumber operator - (const BigNumber &a,const BigNumber &b){
BigNumber c;
c.d[0]=a.d[0];
int i,x=0;
for(i=1;i<=c.d[0];i++){
x=10000+a.d[i]-b.d[i]+x;
c.d[i]=x%10000;
x=x/10000-1;
}
while((c.d[0]>1)&&(c.d[c.d[0]]==0))--c.d[0];
return c;
}
bool smaller(const BigNumber &a,const BigNumber &b,int delta){
if(a.d[0]+delta!=b.d[0])return a.d[0]+delta<b.d[0];
int i;
for(i=a.d[0];i>0;i--)
if(a.d[i]!=b.d[i+delta])
return a.d[i]<b.d[i+delta];
return true;
}
void Minus(BigNumber &a,const BigNumber &b,int delta){
int i,x=0;
for(int i=1;i<=a.d[0]-delta;i++){
x=10000+a.d[i+delta]-b.d[i]+x;
a.d[i+delta]=x%10000;
x=x/10000-1;
}
while((a.d[0]>1)&&(a.d[a.d[0]]==0))a.d[0]--;
}
BigNumber operator /(const BigNumber &a,const BigNumber &b)
{
BigNumber c;
d=a;
int i,j,temp;
mid1[0]=b;
for(int i=1; i<=13; i++){
mid1[i]=mid1[i-1]*two;
}
for(i=a.d[0]-b.d[0]; i>=0; i--){
temp=8192;
for(int j=13; j>=0; j--){
if(smaller(mid1[j],d,i)){
Minus(d,mid1[j],i);
c.d[i+1]+=temp;
}
temp/=2;
}
}
c.d[0]=max(1,a.d[0]-b.d[0]+1);
while((c.d[0]>1)&&(c.d[c.d[0]]==0))--c.d[0];
return c;
}
BigNumber qpow(BigNumber a,int n){
BigNumber ans=one;
while(n){
if(n&1){
ans=ans*a;
}
a=a*a;
n>>=1;
}
return ans;
}
BigNumber f1,f2,f3,d1,d2,d3;
void init()
{
f1=one,f2=one+one,f3=one+one+one+one+one;
d1=one,d2=one+one+one,d3=one+one+one+one+one+one+one;
}
void solve()
{
int n;
scanf("%d",&n);
BigNumber ans=qpow(two,(n+1));
if(n&1){
ans=ans-one;
ans=ans/three;
}else{
ans=ans-two;
ans=ans/three;
}
cout<<ans.toString()<<endl;
}
int main(){
init();
int T;
scanf("%d",&T);
while(T--){
solve();
}
return 0;
}