UVA1374 题意:输入正整数n(1≤n≤1000),问最少需要几次乘除法可以从x得到x^n?例如,x^31需要6次 。 计算过程中x的指数应当总是正整数(如x^-3=x/x^4是不允许的)。
我对这个题目理解得不正确,而且是多次不正确。
通过P211的图,我更好明白了每层扩展这能有1个,不能分叉都兼得。对深搜也有更好地认识了。实际上,小于logn的层都是找不到的。
这是我错误的代码:
#include<vector>
#include<algorithm>
#include<ctime>
#include<iostream>
#include<set>
using namespace std;
#define iMax 100
typedef struct{
int x; //元素
int v; //得到这个元素的计算成本
}node;
node F[5000];
int main()
{
void compute(int i,int j,int & kk_n,int k);
node tofind(int n,int kk_n);
int n=1;
while(scanf("%d",&n)&&n)
{
int k=0,kk;
node pa;
pa.x=1;
pa.v=0;
F[0]=(pa);
int k_n=1,n_k_n;
int last=1;
while(true)
{
n_k_n=k_n;
for(int i=0;i<k_n;i++)
for(int j=i;j>=i&&j<k_n;j++)
{
compute(i,j,n_k_n,k_n); //存在则更新最小值,否则添加
//cout<<"ij"<<i<<""<<j<<endl;
}
k_n=n_k_n;
//for(int i=0;i<n_k_n;i++)
//cout<<F[i].x<<" "<<F[i].v<<endl;
//cout<<" --------------------"<<endl;
pa=tofind(n,k_n);
if(pa.x>0)
{
if(!last)
{cout<<pa.v<<endl; break;}
last--;
}
}
n++;
}
}
void compute(int i,int j,int & kk_n,int k)
{
node ni,nj,n1,n2,n3,n4;
int n1_=iMax,n2_=iMax,n3_=iMax,n4_=iMax,oldkk_n=k;
ni=F[i];
nj=F[j];
n1.x=2*ni.x;
n1.v=ni.v+1;
n2.x=ni.x+nj.x;
n2.v=ni.v+nj.v+1;
if(nj.x%ni.x==0) n2.v=min(ni.v+nj.x/ni.x,n2.v);
n3.x=nj.x-ni.x;
n3.v=ni.v+nj.v+1;
n4.x=2*nj.x;
n4.v=nj.v+1;
//if(n4.x==953||n3.x==953||n2.x==953||n1.x==953)
//cout<<"----------"<<i<<" "<<j<<endl;
for(int s=0;s<oldkk_n;s++)
{
if(F[s].x==n1.x)
{
F[s].v=min(n1.v,F[s].v);
n1_=min(n1.v,F[s].v);
}
if(F[s].x==n2.x)
{
F[s].v=min(n2.v,F[s].v);
n2_=min(n2.v,F[s].v);
}
if(F[s].x==n3.x&&i!=j)
{
F[s].v=min(n3.v,F[s].v);
n3_=min(n3.v,F[s].v);
}
if(F[s].x==n4.x)
{
F[s].v=min(n4.v,F[s].v);
n4_=min(n4.v,F[s].v);
}
}
if(n1_==iMax&&n1.x>0)
{
for(int s=oldkk_n-1;s<kk_n;s++)
{
if(F[s].x==n1.x)
{
F[s].v=min(n1.v,F[s].v);
n1_=min(n1.v,F[s].v);
break;
}
}
if(n1_==iMax) F[kk_n++]=n1;
}
if(n2_==iMax&&n2.x>0)
{
for(int s=oldkk_n-1;s<kk_n;s++)
{
if(F[s].x==n2.x)
{
F[s].v=min(n2.v,F[s].v);
n2_=min(n2.v,F[s].v);
break;
}
}
if(n2_==iMax) F[kk_n++]=n2;//cout<<kk_n<<endl;}
}
if(n3_==iMax&&i!=j&&n3.x>0)
{
for(int s=oldkk_n-1;k<kk_n;k++)
{
if(F[s].x==n3.x)
{
F[s].v=min(n3.v,F[s].v);
n3_=min(n3.v,F[s].v);
break;
}
}
if(n3_==iMax) F[kk_n++]=n3;
}
if(n4_==iMax&&n4.x>0)
{
for(int s=oldkk_n-1;s<kk_n;s++)
{
if(F[s].x==n4.x)
{
F[s].v=min(n4.v,F[s].v);
n4_=min(n4.v,F[s].v);
break;
}
}
if(n4_==iMax) F[kk_n++]=n4;
}
}
node tofind(int n,int kk_n)
{
int i;
node pa;
pa.x=-1;
pa.v=iMax;
for(i=0;i<kk_n;i++)
if(F[i].x==n)
{
if(F[i].v<pa.v) pa=F[i];
}
return pa;
}
这个代码存在问题,比如说27 需要先计算出9,然后相乘两次就行,计算9需要4次,所以共有6次就够了。但是我的这个程序无法得到正确答案,没有更好处理好node.V的计算方法。