征求一算法. (看来都嫌分少,这样吧再加300,一共400了) (100分)

  • 主题发起人 LeeChange
  • 开始时间
A

AI_Player

Unregistered / Unconfirmed
GUEST, unregistred user!
我想先定一个方向,如果步数超过总数的一半,就说明应该是另一个方向,再换(不过这样程序就比较复杂了)
 
L

LeeChange

Unregistered / Unconfirmed
GUEST, unregistred user!
呵呵,不光程序复杂,用双向所节省的时间空间复杂度说不定又回来了。
 
A

AI_Player

Unregistered / Unconfirmed
GUEST, unregistred user!
Sorry,我发现忽略了一个非常重要的问题--这题的状态数只有256个!太失败了!
当我没说过,你们继续……
 
L

LeeChange

Unregistered / Unconfirmed
GUEST, unregistred user!
呵呵,欢迎讨论。
 

叶不归

Unregistered / Unconfirmed
GUEST, unregistred user!
LeeChange, 你不是已经有程序了吗?为什么还要?
 
L

LeeChange

Unregistered / Unconfirmed
GUEST, unregistred user!
呵呵,理由见此问的第一句话.
 
T

top gun

Unregistered / Unconfirmed
GUEST, unregistred user!
to: leechange,叶不归
各位大侠好,小弟也是学计算机的,以前忽视了算法。
现在想学,不知道各位能不能教我。
msn:xiaofang8234◎msn.com
 
X

xd0

Unregistered / Unconfirmed
GUEST, unregistred user!
这种题目实在是简单,在初中的信息学奥林匹克竞赛书上都有。
就是creation-zy的那种思想了~~~~~
想学好算法要多做题哟。
 
L

LeeChange

Unregistered / Unconfirmed
GUEST, unregistred user!
to xd0:
期待您出手.
 
L

ligia

Unregistered / Unconfirmed
GUEST, unregistred user!
比较困难啊,踢一下
 
H

hfghfghfg

Unregistered / Unconfirmed
GUEST, unregistred user!
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, StdCtrls;
type
TMyAAA = record
myface: integer;
myreverse: integer;
mydiff: integer;
end;

type
TForm1 = class(TForm)
Button1: TButton;
Edit1: TEdit;
Edit2: TEdit;
Label1: TLabel;
Label2: TLabel;
StringGrid1: TStringGrid;
Label3: TLabel;
Edit3: TEdit;
procedure Button1Click(Sender: TObject);
private
function MYcheck(V: integer): boolean;
public
{ Public declarations }
end;

var
Form1: TForm1;
implementation
{$R *.dfm}
function mytostr(V1, v2, v3, v4, oldcol, oldrow: integer): string;
begin
result := format('正%d 反%d|由Cells[%d, %d]翻开%d个正的和%d个反的', [V1, V2, oldcol, oldrow, V3, v4]);
end;

function mytoint(v: string): integer;
begin
result := strtoint(trim(copy(v, 3, pos(' ', v) - 2)));
end;

function TForm1.MYcheck(V: integer): boolean;
var
i: integer;
str: string;
begin
for i := 0 to StringGrid1.ColCount - 1do
begin
str := StringGrid1.Cells[i, v];
if str <> '' then
if mytoint(str) = 0 then
begin
result := false;
StringGrid1.Cells[i, v] := StringGrid1.Cells[i, v] + ' 解!';
showmessage(format('解cell[%d,%d]', [i, v]));
exit;
end;
end;
for i := 0 to StringGrid1.ColCount - 1do
begin
str := StringGrid1.Cells[i, v];
if str <> '' then
if mytoint(str) > 0 then
begin
result := true;
exit;
end;
end;
result := false;
showmessage('无解');
end;

procedure TForm1.Button1Click(Sender: TObject);
var
MyAAA: array of TMyAAA;
nowrow, MyAll, target, everyCount, i, m, j, tempmyface, tempmyreverse: integer;
procedure dd(V: integer);
var
i, j: integer;
myreverse, myface: integer;
begin
setlength(MyAAA, 1);
MyAAA[0].mydiff := v;
MyAAA[0].myface := v;
MyAAA[0].myreverse := 0;
for i := 1 to (v div 2)do
begin
myreverse := i;
myface := v - i;
if myface - myreverse > 0 then
begin
j := length(MyAAA);
setlength(MyAAA, j + 1);
MyAAA[j].mydiff := myface - myreverse;
MyAAA[j].myface := myface;
MyAAA[j].myreverse := myreverse;
end;
end;
end;

begin

MyAll := strtoint(edit1.Text);
target := strtoint(edit2.Text);
everyCount := strtoint(edit3.Text);
with StringGrid1do
begin
for i := 0 to rowcount - 1do
for j := 0 to colcount - 1do
Cells[j, i] := '';
rowcount := 1;
colcount := 1;
StringGrid1.Cells[0, 0] := format('正%d 反%d', [target, MyAll - target]);
end;
dd(everyCount);
nowrow := 0;
while MYcheck(nowrow)do
begin
j := 0;
for i := 0 to StringGrid1.ColCount - 1do
if StringGrid1.Cells[i, nowrow] <> '' then
begin
tempmyface := mytoint(StringGrid1.Cells[i, nowrow]);
tempmyreverse := MyAll - tempmyface;
for m := low(MyAAA) to high(MyAAA)do
if tempmyface >= MyAAA[m].myface then
if tempmyreverse >= MyAAA[m].myreverse then
begin
StringGrid1.Cells[j, nowrow + 1] := mytostr(tempmyface - MyAAA[m].mydiff, tempmyreverse + MyAAA[m].mydiff, MyAAA[m].myface, MyAAA[m].myreverse, i, nowrow);
j := j + 1;
end;
end;
if j > StringGrid1.ColCount then
StringGrid1.ColCount := j;
StringGrid1.RowCount := StringGrid1.RowCount + 1;
nowrow := nowrow + 1;
end;
end;

end.


object Form1: TForm1
Left = 63
Top = 146
Width = 795
Height = 375
Caption = 'Form1'
Color = clBtnFace
Font.Charset = GB2312_CHARSET
Font.Color = clWindowText
Font.Height = -14
Font.Name = '宋体'
Font.Style = []
OldCreateOrder = False
Position = poScreenCenter
PixelsPerInch = 96
TextHeight = 14
object Label1: TLabel
Left = 3
Top = 12
Width = 21
Height = 14
Caption = 'All'
end
object Label2: TLabel
Left = 3
Top = 36
Width = 14
Height = 14
Caption = '正'
end
object Label3: TLabel
Left = 3
Top = 60
Width = 28
Height = 14
Caption = '每次'
end
object Button1: TButton
Left = 184
Top = 8
Width = 75
Height = 25
Caption = '开始'
TabOrder = 0
OnClick = Button1Click
end
object Edit1: TEdit
Left = 32
Top = 8
Width = 121
Height = 22
TabOrder = 1
Text = '20'
end
object Edit2: TEdit
Left = 32
Top = 32
Width = 121
Height = 22
TabOrder = 2
Text = '13'
end
object StringGrid1: TStringGrid
Left = 0
Top = 88
Width = 787
Height = 260
Align = alBottom
DefaultColWidth = 280
DefaultRowHeight = 20
FixedCols = 0
FixedRows = 0
Font.Charset = GB2312_CHARSET
Font.Color = clWindowText
Font.Height = -12
Font.Name = '宋体'
Font.Style = []
ParentFont = False
TabOrder = 3
end
object Edit3: TEdit
Left = 32
Top = 56
Width = 121
Height = 22
TabOrder = 4
Text = '5'
end
end

 
L

LeeChange

Unregistered / Unconfirmed
GUEST, unregistred user!
to hfghfghfg:
all: 21
正: 9
每次翻4个是有解的,您的程序说没有解.
我有一点觉的奇怪,您的程序为什么从初始状态往后只搜索了翻4个正面和翻3个正面两种情况?
翻2个的翻一个的也得试试吧.
 
V

vividw

Unregistered / Unconfirmed
GUEST, unregistred user!
这个问题 可以查一些关于数论的知识
尝试证明些 猜想
 
F

fu_qi_ming

Unregistered / Unconfirmed
GUEST, unregistred user!
K

kerbcurb

Unregistered / Unconfirmed
GUEST, unregistred user!
再改!
//---------------------------------------------------------------------------
#include <math.h>
#include <iostream.h>
#include <conio.h>
#pragma hdrstop
//---------------------------------------------------------------------------
#pragma argsused
int main(int argc, char* argv[])
{
unsigned a,b,n,a1,b1,Num,x;
bool t;
char ch;
aa:
cout <<"a = ";
cin >>a;
cout <<"b = ";
cin >>b;
cout <<"n = ";
cin >>n;
for (int k = 0;k <=n;k++)
{
a1 = a + n - 2 * k;
b1 = b - n + 2 * k;
if(a1>=0&amp;&amp;b1>=0)
{
if(!fmod(a1,n))
{
t = true;
Num = a1 / n + 1;
x = k;
break;
}
else
if(!fmod(b1,n))
{
t = true;
Num = b1 / n + 1;
x = k;
break;
}
if(!fmod(a1,n)&amp;&amp;!fmod(b1,n))
{
t = true;
Num = b1 / n + 1;
x = k;
break;
}
}
}
if(x == 0)Num = 1;
if(t)cout << "Is true,"<<" Num = "<< Num<<" ,k = "<< x <<endl;
else
cout << "Is false!"<<endl;
ch = getch();
if(ch != 'q')goto aa;
return 0;
}
//---------------------------------------------------------------------------
改了改,不知道行不行,请你给出反例,以便改进,执行你的10,23,11,和108,123,10以及8,23,8的例子没有问题,当然程序还有一点小问题需要规范
 
L

LeeChange

Unregistered / Unconfirmed
GUEST, unregistred user!
不行.
但每个人的代码都会对我有所帮助.谢谢.
 
L

LeeChange

Unregistered / Unconfirmed
GUEST, unregistred user!
谁一个劲帮我提前呀,谢谢.
 
K

kerbcurb

Unregistered / Unconfirmed
GUEST, unregistred user!
我已经改了,你试一试,你的那几种情况,都可以,因为我是从新编辑,所以你可能没发现
 
K

kerbcurb

Unregistered / Unconfirmed
GUEST, unregistred user!
以下问题未作考虑:
1)n=1每次翻一个
2)a或b是n的倍数
程序中:a、b分别代表正面、反面硬币的数目,n代表每次要求翻的数目,a+b可以大于255
问题的算法实际上是枚举法:
1)如果a或b是n的倍数,直接用除法就可得出
2)否则,a翻k个,则b被翻n-k个,翻一次后a、b分别变为a-k+(n-k)=a+n-2*k个,b-(n-k)+k=b-n+2*k个,让k从0到n,看a、b谁能被n整除,如果都不能无解,如果能,除法计算即可得到
 

Similar threads

S
回复
0
查看
3K
SUNSTONE的Delphi笔记
S
S
回复
0
查看
2K
SUNSTONE的Delphi笔记
S
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
2K
DelphiTeacher的专栏
D
D
回复
0
查看
1K
DelphiTeacher的专栏
D
顶部