求教一个数学题的编程方法!(100分)

  • 主题发起人 主题发起人 xdenver
  • 开始时间 开始时间
X

xdenver

Unregistered / Unconfirmed
GUEST, unregistred user!
有这样一个题:有1,2,3,4,5,6,7,8 这8个数字
在下面这个空空里填写 ___ ___ ___ ×___ = ___ ___ ___ ___ 满足一个3位数乘以一个1位数等于一个4位数。把这8个数字分别填写到8个空里,且不能重复!

对于这个问题,怎么编程实现!
特向各位高人请教
 
用穷举法看看行不
 
窮舉法.

var iTemp1,iTemp2,iTemp3,iTemp4,iTemp5,iTemp6,iTemp7,iTemp8:Integer;
begin
for iTemp1:=2 to 8 do --第一位不可能是1
for iTemp2:=1 to 8 do
for iTemp3:=1 to 8 do
for iTemp4:=1 to 8 do
for iTemp5:=1 to 6 do --千分位不可能大于7 800*8=6400
for iTemp6:=1 to 8 do
for iTemp7:=1 to 8 do
for iTemp8:=1 to 8 do
if (iTemp1<>iTemp2) and (iTemp1<>iTemp3) and (iTemp1<>iTemp4) and (iTemp1<>iTemp5) and (iTemp1<>iTemp6) and (iTemp1<>iTemp7) and (iTemp1<>iTemp8) and
(iTemp2<>iTemp3) and (iTemp2<>iTemp4) and (iTemp2<>iTemp5) and (iTemp2<>iTemp6) and (iTemp2<>iTemp7) and (iTemp2<>iTemp8) and
(iTemp3<>iTemp4) and (iTemp3<>iTemp5) and (iTemp3<>iTemp6) and (iTemp3<>iTemp7) and (iTemp3<>iTemp8) and
(iTemp4<>iTemp5) and (iTemp4<>iTemp6) and (iTemp4<>iTemp7) and (iTemp4<>iTemp8) and
(iTemp5<>iTemp6) and (iTemp5<>iTemp7) and (iTemp5<>iTemp8) and
(iTemp6<>iTemp7) and (iTemp6<>iTemp8) and
(iTemp7<>iTemp8) and
( (iTemp3*iTemp4-iTemp8) mod 10=0 ) and --減少一些工作量,不要也行.
( (iTemp1*100+iTemp2*10+iTemp3)*iTemp4=iTemp5*1000+iTemp6*100+iTemp7*10+iTemp8 ) then
begin
ShowMessage(IntToStr(iTemp1)+IntToStr(iTemp2)+IntToStr(iTemp3)+'X'+IntToStr(iTemp4)+'='+IntToStr(iTemp5)+IntToStr(iTemp6)+IntToStr(iTemp7)+IntToStr(iTemp8));
end;
 
数字全排列问题:
  任意给出从1到N的N个连续的自然数,求出这N个自然数的各种全排列。如N=3时,共有以下6种排列方式:
123,132,213,231,312,321。
注意:数字不能重复,N由键盘输入(N<=9)。

解题思路:
  应用回溯法,每个数的取法都有N个方向(1——N),当取够N个数时,输出一个排列,然后退后一步,取前一个数的下一个方向(即前一个数+1),并且要保证所有数字不能重复。当前数字的所有方向都取完时,继续退一步,一直重复到第一个数为止。

程序代码:

program quanpailie; {数字全排列问题}
var
a:array[1..9] of integer;
k,x,n:integer;

function panduan(j,h:integer):boolean; {判断当前数字是否能赋值给当前数组元素}
var
m:integer;
begin
panduan:=true;
for m:=1 to h-1 do
if a[m]=j then panduan:=false {如果当前数字与前面的数组元素相同则不能赋值}
end;

procedure try(h:integer);
var
i,j,m:integer;
begin
for j:=1 to n do
if panduan(j,h) then
begin
a[h]:=j; {能够赋值,且长度k加一}
k:=k+1;
if k=n then {如果长度达到N则表示一种组合已经完成,输出结果}
begin
for m:=1 to n do
write(a[m]);
write('':4);
x:=x+1; {每输出一种排列方式加一}
if x mod 5=0 then writeln; {每行输出5种排列方案}
end
else
try(h+1); {对下一个数组元素进行赋值}
k:=k-1 {回溯的时候一定要把长度减一}
end
end;

begin
writeln('输入 N:');
readln(n);
k:=0; {k表示长度,长度初始值为0}
x:=0; {x表示总的排列方式}
try(1); {对第一个数组元素赋值}
writeln('共有 ', x ,' 种排列方案')
end.
 
procedure TForm1.Button1Click(Sender: TObject);
type
TmyArray = Array[0..7] Of Integer;
var i,j,m,k,t:integer;
s:string;
a1,a2,a3,a4,a5,a6,a7,a8:integer;
myarray : TmyArray;
bm:boolean;
begin
for j:=2 to 8 do
begin
for i:=123 to 987 do
begin
m:=i*j;
s:=''+IntToStr(i)+'*'+IntToStr(j)+'='+IntToStr(m)+'';

if m>1000 then
begin
a1:=StrToInt(copy(IntToStr(i),1,1));
a2:=StrToInt(copy(IntToStr(i),2,1));
a3:=StrToInt(copy(IntToStr(i),3,1));
a4:=StrToInt(copy(IntToStr(m),1,1));
a5:=StrToInt(copy(IntToStr(m),2,1));
a6:=StrToInt(copy(IntToStr(m),3,1));
a7:=StrToInt(copy(IntToStr(m),4,1));
a8:=j;
if (a1+a2+a3+a4+a5+a6+a7+a8=36) then
begin
if (a1>0) and (a1<9) and (a2>0) and (a2<9) and (a3>0) and (a3<9) and
(a4>0) and (a4<9) and (a5>0) and (a5<9) and (a6>0) and (a6<9) and (a7>0) and (a7<9) then
begin
myarray[0]:=a1;
myarray[1]:=a2;
myarray[2]:=a3;
myarray[3]:=a4;
myarray[4]:=a5;
myarray[5]:=a6;
myarray[6]:=a7;
myarray[7]:=a8;
bm:=false;
for k:=0 to 7 do
begin
for t:=0 to 7 do
begin
if (k<>t) and (myarray[k]=myarray[t]) then
begin
bm:=True;
end;
end;
end;
if bm=false then Memo1.Lines.Add(s);
end;
end;
end;
end;
end;

end;
 
高!实在的高
 
后退
顶部