计算机算法设计与分析作业01:分治法求解大数乘法+L型骨牌的棋盘覆盖问题
2016-09-16 19:32
746 查看
计算机算法设计与分析作业01:分治法求解大数乘法+L型骨牌的棋盘覆盖问题
1.分治法求解大数乘法:
代码实现:
有bug版,主要是add()和sub()函数写的有问题,大数分治的思路是正确的。
代码实现:
完善版,正确。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
void out(int ppp[],int pppn)
{
for(int i=0; i<pppn+2; i++)
{
cout<<ppp[i]<<" ";
}
cout<<endl;
}
void yiwei(int ppp[],int posn)
{
for(int i=ppp[0]+1; i>=2; i--)
{
ppp[i+posn]=ppp[i];
}
for(int i=2; i<2+posn; i++)
{
ppp[i]=0;
}
for(int i=2+ppp[0]+posn; i>=2; i--)
{
if(ppp[i]!=0)
{
ppp[0]=i-2+1;
break;
}
}
}
int max(int *A, int *B) //判断|A|>|B|吗?大于返回1,小于返回-1,等于返回0
{
int i;
if(A[0]>B[0])
return 1;
else if(A[0]<B[0])
return -1;
else
{
i=A[0]+1;
while(i>=2&&A[i]==B[i])
i--;
if(i<2)
return 0;
else if(A[i]>B[i])
return 1;
else
return -1;
}
}
void sublalala(int *A, int * B, int * C) /* 同号的减法运算,要求A,B位数相同,先改成相同的 */
{
int i,d; /* d为借位数 */
if(A[0]>B[0])
{
for(i=B[0]+2; i<=A[0]+1; i++)
B[i]=0;
B[0]=A[0];
}
else if(B[0]>A[0])
{
for(i=A[0]+2; i<=B[0]+1; i++)
A[i]=0;
A[0]=B[0];
}
C[0]=A[0];
d=0;
if(max(A,B)==1)
{
for(i=2; i<=C[0]+1; i++)
{
if(A[i]>=(d+B[i]))
{
C[i]=A[i]-d-B[i];
d=0;
}
else
{
C[i]=A[i]+10-d-B[i];
d=1;
}
}
C[1]=A[1];
}
else
{
for(i=2; i<=C[0]+1; i++)
{
if(B[i]>=(d+A[i]))
{
C[i]=B[i]-d-A[i];
d=0;
}
else
{
C[i]=B[i]+10-d-A[i];
d=1;
}
}
C[1]=A[1]*-1;
}
}
void add(int *A,int *B, int *C) /* C=A+B,带符号的加法运算 */
{
int i,j,d,temp; /* d为进位 */
int D[256];
i=2;
d=0;
if(A[1]*B[1]==1) //A,B同号
{
while(i<=A[0]+1&&i<=B[0]+1)
{
temp=A[i]+B[i]+d;
C[i]=temp%10;
d=temp/10;
i++;
}
while(i<=A[0]+1)
{
temp=A[i]+d;
C[i]=temp%10;
d=temp/10;
i++;
}
while(i<=B[0]+1)
{
temp=B[i]+d;
C[i]=temp%10;
d=temp/10;
i++;
}
if(d>0)
{
C[i]=d;
C[0]=i-1;
}
else
C[0]=i-2;
C[1]=A[1];
}
else //A,B不同号,转换为同号减法
{
D[0]=B[0]; //用D替换一下,保留B的值
D[1]=B[1]*-1;
for(i=2; i<=B[0]+1; i++)
D[i]=B[i];
sublalala(A,D,C);
}
}
void mult(int XX[],int YY[],int nn,int ZZ[])
{
//cout<<endl<<"yilun "<<endl<<endl;
int m1[210],m2[210],m3[210],m4[210],m5[210],m6[210],m7[210],m8[210];
int A[210],B[210],C[210],D[210];///每次都要重新申请A,B,C,D数组
memset(A,0,sizeof(A));
memset(B,0,sizeof(B));
memset(C,0,sizeof(C));
memset(D,0,sizeof(D));
memset(m1,0,sizeof(m1));
memset(m2,0,sizeof(m2));
memset(m3,0,sizeof(m3));
memset(m4,0,sizeof(m4));
memset(m5,0,sizeof(m5));
memset(m6,0,sizeof(m6));
memset(m7,0,sizeof(m7));
memset(m8,0,sizeof(m8));
if(nn==1)
{
ZZ[1]=XX[1]*YY[1];
int tmp=XX[2]*YY[2];
if(tmp>9)
{
ZZ[0]=2;
ZZ[2]=tmp%10;
ZZ[3]=tmp/10;
}
else
{
ZZ[0]=1;
ZZ[2]=tmp;
}
return ;
}
else
{
B[0]=A[0]=nn/2;///进行分治
B[1]=A[1]=XX[1];
for(int i=2; i<2+nn/2; i++)
{
B[i]=XX[i];
}
int k=2;
for(int i=2+nn/2; i<=nn+1; i++)
{
A[k++]=XX[i];
}
C[0]=D[0]=nn/2;
C[1]=D[1]=YY[1];
for(int i=2; i<2+nn/2; i++)
{
D[i]=YY[i];
}
k=2;
for(int i=2+nn/2; i<=nn+1; i++)
{
C[k++]=YY[i];
}
/*cout<<"After fenzhi :"<<endl;///测试分治用
out(A,nn/2);
out(B,nn/2);
out(C,nn/2);
out(D,nn/2);*/
mult(A,C,nn/2,m1);
/*cout<<"chengjim1 :"<<endl;
out(m1,m1[0]);*/
sublalala(A,B,m4);
sublalala(D,C,m5);
/*cout<<"After sub"<<endl;
out(m4,m4[0]);
out(m5,m5[0]);*/
mult(m4,m5,nn/2,m2);
/*cout<<"chengji :"<<endl;
out(m2,m2[0]);*/
mult(B,D,nn/2,m3);
/*cout<<"chengji2 :"<<endl;
out(m3,m3[0]);*/
add(m1,m2,m6);
/*cout<<"m1+m2="<<endl;
out(m6,m6[0]);*/
add(m6,m3,m7);
/*cout<<"m1+m2+m3="<<endl;
out(m7,m7[0]);*/
yiwei(m7,nn/2);
//out(m7,m7[0]);
yiwei(m1,nn);
/*cout<<"m1yiweihou"<<endl;
out(m1,m1[0]);*/
add(m1,m7,m8);
/*cout<<"m8="<<endl;
out(m8,m8[0]);*/
add(m8,m3,ZZ);
/*cout<<"ZZ==="<<endl;
out(ZZ,ZZ[0]);*/
}
}
int main()
{
char xx[210],yy[210];
int X[210],Y[210],Z[500];
int n;
while(scanf("%s%s",xx,yy)!=EOF)///输入两个长度相等且都为2^n的字符串(不带正负号)
{
int k;
n=strlen(xx);
if(xx[0]=='-')
{
X[1]=-1;
k=n;
for(int i=1; i<n; i++)
{
X[k--]=xx[i]-'0';
}
}
else
{
X[1]=1;
k=n+1;
for(int i=0; i<n; i++)
{
X[k--]=xx[i]-'0';
}
}
int m=strlen(yy);
if(yy[0]=='-')
{
Y[1]=-1;
k=m;
for(int i=1; i<m; i++)
{
Y[k--]=yy[i]-'0';
}
}
else
{
Y[1]=1;
k=m+1;
for(int i=0; i<m; i++)
{
Y[k--]=yy[i]-'0';
}
}
n=min(n,m);
X[0]=Y[0]=n;
///把字符数组转化为int数组,并进行逆序
/*cout<<"The chushizhi is:"<<endl;
out(X,n);
out(Y,n);*/
memset(Z,0,sizeof(Z));///最终存放结果
mult(X,Y,n,Z);
//add(X,Y,Z);
if(X[1]==Y[1])
Z[1]=1;
else
Z[1]=-1;
//yiwei(X,2);//测试移位用
//out(X,n+2);
cout<<"The answer is:"<<endl;
if(Z[1]==-1)
printf("-");
for(int i=Z[0]+1; i>=2; i--)
{
printf("%d",Z[i]);
}
printf("\n");
memset(X,0,sizeof(X));
memset(Y,0,sizeof(Y));
/*int ans[210];//测试加减法用
memset(ans,0,sizeof(ans));
sub(X,Y,ans);
out(ans,ans[0]);
memset(ans,0,sizeof(ans));
add(X,Y,ans);
out(ans,ans[0]);*/
}
return 0;
}
2.L型骨牌的棋盘覆盖问题:
代码实现:
1.分治法求解大数乘法:
代码实现:
有bug版,主要是add()和sub()函数写的有问题,大数分治的思路是正确的。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; void out(int ppp[],int pppn) { for(int i=0; i<pppn+2; i++) { cout<<ppp[i]<<" "; } cout<<endl; } void yiwei(int ppp[],int posn) { for(int i=ppp[0]+1; i>=2; i--) { ppp[i+posn]=ppp[i]; } for(int i=2; i<2+posn; i++) { ppp[i]=0; } for(int i=2+ppp[0]+posn; i>=2; i--) { if(ppp[i]!=0) { ppp[0]=i-2+1; break; } } } void sub(int a1[],int b1[],int c1[]) { memset(c1,0,sizeof(c1)); if(a1[1]==1&&b1[1]==-1)///正数减负数,相当于两个正数相加 { c1[1]=1; int i; int nnn=min(a1[0],b1[0]); for(i=2; i<nnn+2; i++) { int tmp=a1[i]+b1[i]; c1[i]+=tmp%10; c1[i+1]=tmp/10; } if(nnn<a1[0]) { int j; for(j=i;j<a1[0]+2;j++) { int tmp=a1[j]+c1[j]; c1[j]=tmp%10; c1[j+1]=tmp/10; } if(c1[j]>0) { c1[0]=a1[0]+1; } else { c1[0]=a1[0]; } //out(c1,c1[0]); } else { int j; for(j=i;j<b1[0]+2;j++) { int tmp=b1[j]+c1[j]; c1[j]=tmp%10; c1[j+1]=tmp/10; } if(c1[j]>0) { c1[0]=b1[0]+1; } else { c1[0]=b1[0]; } //out(c1,c1[0]); } } else if(a1[1]==-1&&b1[1]==1)///负数减正数,相当于两个负数相加 { c1[1]=-1; int i; int nnn=min(a1[0],b1[0]); for(i=2; i<nnn+2; i++) { int tmp=a1[i]+b1[i]; c1[i]+=tmp%10; c1[i+1]=tmp/10; } if(nnn<a1[0]) { int j; for(j=i;j<a1[0]+2;j++) { int tmp=a1[j]+c1[j]; c1[j]=tmp%10; c1[j+1]=tmp/10; } if(c1[j]>0) { c1[0]=a1[0]+1; } else { c1[0]=a1[0]; } //out(c1,c1[0]); } else { int j; for(j=i;j<b1[0]+2;j++) { int tmp=b1[j]+c1[j]; c1[j]=tmp%10; c1[j+1]=tmp/10; } if(c1[j]>0) { c1[0]=b1[0]+1; } else { c1[0]=b1[0]; } //out(c1,c1[0]); } } else if(a1[1]==1 && b1[1]==1) ///正数减正数,先减一次判断一下符号,若为大数减小数, {///则直接减,若为小数减大数,则要重新减一次;负数减负数同样,但需要注意符号 int aa1[210]; int bb1[210]; memset(aa1,0,sizeof(aa1)); memset(bb1,0,sizeof(bb1)); for(int i=0; i<a1[0]+2; i++) { aa1[i]=a1[i]; } for(int i=0; i<b1[0]+2; i++) { bb1[i]=b1[i]; } /*out(aa1,aa1[0]); out(bb1,bb1[0]); out(c1,c1[0]);*/ for(int i=2; i<aa1[0]+2; i++) { if(aa1[i]>=bb1[i]) { c1[i]=aa1[i]-bb1[i]; } else { c1[i]=aa1[i]+10-bb1[i]; aa1[i+1]--; } } if(aa1[aa1[0]+2]==-1) { c1[1]=-1; memset(aa1,0,sizeof(aa1)); for(int i=0; i<a1[0]+2; i++) { aa1[i]=a1[i]; } for(int i=0; i<b1[0]+2; i++) { bb1[i]=b1[i]; } for(int i=2; i<aa1[0]+2; i++) { if(bb1[i]>=aa1[i]) { c1[i]=bb1[i]-aa1[i]; } else { c1[i]=bb1[i]+10-aa1[i]; bb1[i+1]--; } } } else { c1[1]=1; } for(int i=aa1[0]+5; i>=2; i--) { if(c1[i]!=0) { c1[0]=i-2+1; break; } } } else if(a1[1]==-1 && b1[1]==-1) { int aa1[210]; int bb1[210]; memset(aa1,0,sizeof(aa1)); memset(bb1,0,sizeof(bb1)); for(int i=0; i<a1[0]+2; i++) { aa1[i]=a1[i]; } for(int i=0; i<b1[0]+2; i++) { bb1[i]=b1[i]; } for(int i=2; i<bb1[0]+2; i++) { if(bb1[i]>=aa1[i]) { c1[i]=bb1[i]-aa1[i]; } else { c1[i]=bb1[i]+10-aa1[i]; bb1[i+1]--; } } if(bb1[bb1[0]+2]==-1) { c1[1]=-1; memset(aa1,0,sizeof(aa1)); for(int i=0; i<a1[0]+2; i++) { aa1[i]=a1[i]; } memset(bb1,0,sizeof(bb1)); for(int i=0; i<b1[0]+2; i++) { bb1[i]=b1[i]; } for(int i=2; i<bb1[0]+2; i++) { if(aa1[i]>=bb1[i]) { c1[i]=aa1[i]-bb1[i]; } else { c1[i]=aa1[i]+10-bb1[i]; aa1[i+1]--; } } } else { c1[1]=-1; } for(int i=aa1[0]+5; i>=2; i--) { if(c1[i]!=0) { c1[0]=i-2+1; break; } } } } void add(int a1[],int b1[],int c1[]) { if(a1[1]==b1[1]) { c1[1]=a1[1]; int i; int nnn=min(a1[0],b1[0]); for(i=2; i<nnn+2; i++) { int tmp=a1[i]+b1[i]; c1[i]+=tmp%10; c1[i+1]=tmp/10; } if(nnn<a1[0]) { int j; for(j=i;j<a1[0]+2;j++) { int tmp=a1[j]+c1[j]; c1[j]=tmp%10; c1[j+1]=tmp/10; } if(c1[j]>0) { c1[0]=a1[0]+1; } else { c1[0]=a1[0]; } //out(c1,c1[0]); } else { int j; for(j=i;j<b1[0]+2;j++) { int tmp=b1[j]+c1[j]; c1[j]=tmp%10; c1[j+1]=tmp/10; } if(c1[j]>0) { c1[0]=b1[0]+1; } else { c1[0]=b1[0]; } //out(c1,c1[0]); } } else if(a1[1]==-1&&b1[1]==1) { int aa1[210]; memset(aa1,0,sizeof(aa1)); for(int i=0; i<a1[0]+2; i++) { aa1[i]=a1[i]; } aa1[1]=1; sub(b1,aa1,c1); } else if(a1[1]==1 && b1[1]==-1) { int bb1[210]; memset(bb1,0,sizeof(bb1)); for(int i=0; i<b1[0]+2; i++) { bb1[i]=b1[i]; } bb1[1]=1; sub(a1,bb1,c1); } } void mult(int XX[],int YY[],int nn,int ZZ[]) { //cout<<endl<<"yilun "<<endl<<endl; int m1[210],m2[210],m3[210],m4[210],m5[210],m6[210],m7[210],m8[210]; int A[210],B[210],C[210],D[210];///每次都要重新申请A,B,C,D数组 memset(A,0,sizeof(A)); memset(B,0,sizeof(B)); memset(C,0,sizeof(C)); memset(D,0,sizeof(D)); memset(m1,0,sizeof(m1)); memset(m2,0,sizeof(m2)); memset(m3,0,sizeof(m3)); memset(m4,0,sizeof(m4)); memset(m5,0,sizeof(m5)); memset(m6,0,sizeof(m6)); memset(m7,0,sizeof(m7)); memset(m8,0,sizeof(m8)); if(nn==1) { ZZ[1]=XX[1]*YY[1]; int tmp=XX[2]*YY[2]; if(tmp>9) { ZZ[0]=2; ZZ[2]=tmp%10; ZZ[3]=tmp/10; } else { ZZ[0]=1; ZZ[2]=tmp; } return ; } else { B[0]=A[0]=nn/2;///进行分治 B[1]=A[1]=XX[1]; for(int i=2; i<2+nn/2; i++) { B[i]=XX[i]; } int k=2; for(int i=2+nn/2; i<=nn+1; i++) { A[k++]=XX[i]; } C[0]=D[0]=nn/2; C[1]=D[1]=YY[1]; for(int i=2; i<2+nn/2; i++) { D[i]=YY[i]; } k=2; for(int i=2+nn/2; i<=nn+1; i++) { C[k++]=YY[i]; } /*cout<<"After fenzhi :"<<endl;///测试分治用 out(A,nn/2); out(B,nn/2); out(C,nn/2); out(D,nn/2);*/ mult(A,C,nn/2,m1); /*cout<<"chengjim1 :"<<endl; out(m1,m1[0]);*/ sub(A,B,m4); sub(D,C,m5); /*cout<<"After sub"<<endl; out(m4,m4[0]); out(m5,m5[0]);*/ mult(m4,m5,nn/2,m2); /*cout<<"chengji :"<<endl; out(m2,m2[0]);*/ mult(B,D,nn/2,m3); /*cout<<"chengji2 :"<<endl; out(m3,m3[0]);*/ add(m1,m2,m6); /*cout<<"m1+m2="<<endl; out(m6,m6[0]);*/ add(m6,m3,m7); /*cout<<"m1+m2+m3="<<endl; out(m7,m7[0]);*/ yiwei(m7,nn/2); //out(m7,m7[0]); yiwei(m1,nn); /*cout<<"m1yiweihou"<<endl; out(m1,m1[0]);*/ add(m1,m7,m8); /*cout<<"m8="<<endl; out(m8,m8[0]);*/ add(m8,m3,ZZ); /*cout<<"ZZ==="<<endl; out(ZZ,ZZ[0]);*/ } } int main() { char xx[210],yy[210]; int X[210],Y[210],Z[500]; int n; while(scanf("%s%s",xx,yy)!=EOF)///输入两个长度相等且都为2^n的字符串(不带正负号) { int k; n=strlen(xx); if(xx[0]=='-') { X[1]=-1; k=n; for(int i=1; i<n; i++) { X[k--]=xx[i]-'0'; } } else { X[1]=1; k=n+1; for(int i=0; i<n; i++) { X[k--]=xx[i]-'0'; } } int m=strlen(yy); if(yy[0]=='-') { Y[1]=-1; k=m; for(int i=1; i<m; i++) { Y[k--]=yy[i]-'0'; } } else { Y[1]=1; k=m+1; for(int i=0; i<m; i++) { Y[k--]=yy[i]-'0'; } } n=min(n,m); X[0]=Y[0]=n; ///把字符数组转化为int数组,并进行逆序 /*cout<<"The chushizhi is:"<<endl; out(X,n); out(Y,n);*/ memset(Z,0,sizeof(Z));///最终存放结果 mult(X,Y,n,Z); //add(X,Y,Z); if(X[1]==Y[1]) Z[1]=1; else Z[1]=-1; //yiwei(X,2);//测试移位用 //out(X,n+2); cout<<"The answer is:"<<endl; if(Z[1]==-1) printf("-"); for(int i=Z[0]+1; i>=2; i--) { printf("%d",Z[i]); } printf("\n"); memset(X,0,sizeof(X)); memset(Y,0,sizeof(Y)); /*int ans[210];//测试加减法用 memset(ans,0,sizeof(ans)); sub(X,Y,ans); out(ans,ans[0]); memset(ans,0,sizeof(ans)); add(X,Y,ans); out(ans,ans[0]);*/ } return 0; }
代码实现:
完善版,正确。
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
void out(int ppp[],int pppn)
{
for(int i=0; i<pppn+2; i++)
{
cout<<ppp[i]<<" ";
}
cout<<endl;
}
void yiwei(int ppp[],int posn)
{
for(int i=ppp[0]+1; i>=2; i--)
{
ppp[i+posn]=ppp[i];
}
for(int i=2; i<2+posn; i++)
{
ppp[i]=0;
}
for(int i=2+ppp[0]+posn; i>=2; i--)
{
if(ppp[i]!=0)
{
ppp[0]=i-2+1;
break;
}
}
}
int max(int *A, int *B) //判断|A|>|B|吗?大于返回1,小于返回-1,等于返回0
{
int i;
if(A[0]>B[0])
return 1;
else if(A[0]<B[0])
return -1;
else
{
i=A[0]+1;
while(i>=2&&A[i]==B[i])
i--;
if(i<2)
return 0;
else if(A[i]>B[i])
return 1;
else
return -1;
}
}
void sublalala(int *A, int * B, int * C) /* 同号的减法运算,要求A,B位数相同,先改成相同的 */
{
int i,d; /* d为借位数 */
if(A[0]>B[0])
{
for(i=B[0]+2; i<=A[0]+1; i++)
B[i]=0;
B[0]=A[0];
}
else if(B[0]>A[0])
{
for(i=A[0]+2; i<=B[0]+1; i++)
A[i]=0;
A[0]=B[0];
}
C[0]=A[0];
d=0;
if(max(A,B)==1)
{
for(i=2; i<=C[0]+1; i++)
{
if(A[i]>=(d+B[i]))
{
C[i]=A[i]-d-B[i];
d=0;
}
else
{
C[i]=A[i]+10-d-B[i];
d=1;
}
}
C[1]=A[1];
}
else
{
for(i=2; i<=C[0]+1; i++)
{
if(B[i]>=(d+A[i]))
{
C[i]=B[i]-d-A[i];
d=0;
}
else
{
C[i]=B[i]+10-d-A[i];
d=1;
}
}
C[1]=A[1]*-1;
}
}
void add(int *A,int *B, int *C) /* C=A+B,带符号的加法运算 */
{
int i,j,d,temp; /* d为进位 */
int D[256];
i=2;
d=0;
if(A[1]*B[1]==1) //A,B同号
{
while(i<=A[0]+1&&i<=B[0]+1)
{
temp=A[i]+B[i]+d;
C[i]=temp%10;
d=temp/10;
i++;
}
while(i<=A[0]+1)
{
temp=A[i]+d;
C[i]=temp%10;
d=temp/10;
i++;
}
while(i<=B[0]+1)
{
temp=B[i]+d;
C[i]=temp%10;
d=temp/10;
i++;
}
if(d>0)
{
C[i]=d;
C[0]=i-1;
}
else
C[0]=i-2;
C[1]=A[1];
}
else //A,B不同号,转换为同号减法
{
D[0]=B[0]; //用D替换一下,保留B的值
D[1]=B[1]*-1;
for(i=2; i<=B[0]+1; i++)
D[i]=B[i];
sublalala(A,D,C);
}
}
void mult(int XX[],int YY[],int nn,int ZZ[])
{
//cout<<endl<<"yilun "<<endl<<endl;
int m1[210],m2[210],m3[210],m4[210],m5[210],m6[210],m7[210],m8[210];
int A[210],B[210],C[210],D[210];///每次都要重新申请A,B,C,D数组
memset(A,0,sizeof(A));
memset(B,0,sizeof(B));
memset(C,0,sizeof(C));
memset(D,0,sizeof(D));
memset(m1,0,sizeof(m1));
memset(m2,0,sizeof(m2));
memset(m3,0,sizeof(m3));
memset(m4,0,sizeof(m4));
memset(m5,0,sizeof(m5));
memset(m6,0,sizeof(m6));
memset(m7,0,sizeof(m7));
memset(m8,0,sizeof(m8));
if(nn==1)
{
ZZ[1]=XX[1]*YY[1];
int tmp=XX[2]*YY[2];
if(tmp>9)
{
ZZ[0]=2;
ZZ[2]=tmp%10;
ZZ[3]=tmp/10;
}
else
{
ZZ[0]=1;
ZZ[2]=tmp;
}
return ;
}
else
{
B[0]=A[0]=nn/2;///进行分治
B[1]=A[1]=XX[1];
for(int i=2; i<2+nn/2; i++)
{
B[i]=XX[i];
}
int k=2;
for(int i=2+nn/2; i<=nn+1; i++)
{
A[k++]=XX[i];
}
C[0]=D[0]=nn/2;
C[1]=D[1]=YY[1];
for(int i=2; i<2+nn/2; i++)
{
D[i]=YY[i];
}
k=2;
for(int i=2+nn/2; i<=nn+1; i++)
{
C[k++]=YY[i];
}
/*cout<<"After fenzhi :"<<endl;///测试分治用
out(A,nn/2);
out(B,nn/2);
out(C,nn/2);
out(D,nn/2);*/
mult(A,C,nn/2,m1);
/*cout<<"chengjim1 :"<<endl;
out(m1,m1[0]);*/
sublalala(A,B,m4);
sublalala(D,C,m5);
/*cout<<"After sub"<<endl;
out(m4,m4[0]);
out(m5,m5[0]);*/
mult(m4,m5,nn/2,m2);
/*cout<<"chengji :"<<endl;
out(m2,m2[0]);*/
mult(B,D,nn/2,m3);
/*cout<<"chengji2 :"<<endl;
out(m3,m3[0]);*/
add(m1,m2,m6);
/*cout<<"m1+m2="<<endl;
out(m6,m6[0]);*/
add(m6,m3,m7);
/*cout<<"m1+m2+m3="<<endl;
out(m7,m7[0]);*/
yiwei(m7,nn/2);
//out(m7,m7[0]);
yiwei(m1,nn);
/*cout<<"m1yiweihou"<<endl;
out(m1,m1[0]);*/
add(m1,m7,m8);
/*cout<<"m8="<<endl;
out(m8,m8[0]);*/
add(m8,m3,ZZ);
/*cout<<"ZZ==="<<endl;
out(ZZ,ZZ[0]);*/
}
}
int main()
{
char xx[210],yy[210];
int X[210],Y[210],Z[500];
int n;
while(scanf("%s%s",xx,yy)!=EOF)///输入两个长度相等且都为2^n的字符串(不带正负号)
{
int k;
n=strlen(xx);
if(xx[0]=='-')
{
X[1]=-1;
k=n;
for(int i=1; i<n; i++)
{
X[k--]=xx[i]-'0';
}
}
else
{
X[1]=1;
k=n+1;
for(int i=0; i<n; i++)
{
X[k--]=xx[i]-'0';
}
}
int m=strlen(yy);
if(yy[0]=='-')
{
Y[1]=-1;
k=m;
for(int i=1; i<m; i++)
{
Y[k--]=yy[i]-'0';
}
}
else
{
Y[1]=1;
k=m+1;
for(int i=0; i<m; i++)
{
Y[k--]=yy[i]-'0';
}
}
n=min(n,m);
X[0]=Y[0]=n;
///把字符数组转化为int数组,并进行逆序
/*cout<<"The chushizhi is:"<<endl;
out(X,n);
out(Y,n);*/
memset(Z,0,sizeof(Z));///最终存放结果
mult(X,Y,n,Z);
//add(X,Y,Z);
if(X[1]==Y[1])
Z[1]=1;
else
Z[1]=-1;
//yiwei(X,2);//测试移位用
//out(X,n+2);
cout<<"The answer is:"<<endl;
if(Z[1]==-1)
printf("-");
for(int i=Z[0]+1; i>=2; i--)
{
printf("%d",Z[i]);
}
printf("\n");
memset(X,0,sizeof(X));
memset(Y,0,sizeof(Y));
/*int ans[210];//测试加减法用
memset(ans,0,sizeof(ans));
sub(X,Y,ans);
out(ans,ans[0]);
memset(ans,0,sizeof(ans));
add(X,Y,ans);
out(ans,ans[0]);*/
}
return 0;
}
2.L型骨牌的棋盘覆盖问题:
代码实现:
#include <iostream> #include <cstdio> #include <cmath> using namespace std; const int maxn=2048; int Board[maxn][maxn]; int tile=1; void ChessBoard(int tr,int tc,int dr,int dc,int size_b) { if(size_b==1) return ; int t=tile++,s=size_b/2; if(dr<tr+s && dc<tc+s)//左上角 { ChessBoard(tr,tc,dr,dc,s); } else { Board[tr+s-1][tc+s-1]=t; ChessBoard(tr,tc,tr+s-1,tc+s-1,s); } if(dr<tr+s && dc>=tc+s)//右上角 { ChessBoard(tr,tc+s,dr,dc,s); } else { Board[tr+s-1][tc+s]=t; ChessBoard(tr,tc+s,tr+s-1,tc+s,s); } if(dr>=tr+s && dc<tc+s)//左下角 { ChessBoard(tr+s,tc,dr,dc,s); } else { Board[tr+s][tc+s-1]=t; ChessBoard(tr+s,tc,tr+s,dc+s-1,s); } if(dr>=tr+s && dc>=tc+s)//右下角 { ChessBoard(tr+s,tc+s,dr,dc,s); } else { Board[tr+s][tc+s]=t; ChessBoard(tr+s,tc+s,tr+s,tc+s,s); } } int main() { int n,dr,dc; cout<<"请输入棋盘的边长大小:(2^n)"<<endl; scanf("%d",&n); cout<<"请输入特殊方格的位置:"<<endl; scanf("%d%d",&dr,&dc); cout<<"对棋盘进行覆盖后得到:"<<endl; ChessBoard(0,0,dr,dc,pow(2,n)); for(int i=0;i<pow(2,n);i++) { for(int j=0;j<pow(2,n);j++) { printf("%3d ",Board[i][j]); } cout<<endl; } return 0; }
相关文章推荐
- 计算机算法设计与分析之棋盘覆盖问题
- 计算机算法设计与分析之棋盘覆盖问题
- 算法分析与设计之棋盘覆盖问题
- 算法分析与设计之棋盘覆盖问题
- 【算法设计与分析】2、棋盘覆盖问题
- 高效算法设计_递归与分治(棋盘覆盖问题,循环日程表,巨人与鬼)
- 棋盘覆盖问题算法分析与实现(递归)
- 用递归法:设计算法求解汉诺塔问题,并编程实现。 (1) Hanoi(汉诺)塔问题分析 这是一个古典的数学问题,是一个用递归方法解题的典型例子。问题是这样的:古代有一个梵塔,塔内有3个座 A,B,C
- 棋盘覆盖问题(算法分析)(Java版)
- 棋盘覆盖问题的算法设计
- 算法分析与设计课程作业第十六周——NP-完全问题证明
- 【计算机算法分析】分治法——赛程问题
- 经典算法之棋盘覆盖问题 --分治法
- 算法java实现--分治法--棋盘覆盖问题
- 棋盘覆盖 算法分析、设计与实现(Java)
- 计算机算法的设计与分析
- 动态规划法之投资问题_算法分析与设计
- 基因表达式编程的任务指派问题求解算法设计与实现
- 基因表达式编程的任务指派问题求解算法设计与实现
- 算法分析与设计课程资料:蚂蚁算法的初步研究与计算机模拟