当前位置: 代码迷 >> C语言 >> 悬赏千金求一算法
  详细解决方案

悬赏千金求一算法

热度:131   发布时间:2006-05-20 22:50:00.0
晕..死脑筋..玩笑话也听不出来..我对钱也没兴趣..就是有点激情而已.
哈哈 你给我 我也不知道怎么花
那 疯子 来了..你期待吧...看他有没有好方法~!

----------------解决方案--------------------------------------------------------
我来给你个算法,此方法可以称为模块移动匹配法,方法如下(举例来讲):
1 1 2 2 3 3
你有如下3个模块:
模块1:1 _ 1
模块2:2 _ _ 2
模块3:3 _ _ _ 3
现在保持模块3不动,移动模块2,当模块2处于一个合理的位置后,保持当前状态,然后移动模块1,看是否能够得到有效位置,如果能够,我们就找到了一种可能性。然后继续移动模块1,继续观察,看是否能够找到可能性。直到模块1没有移动可能性。然后我们再移动模块2一个位置,看当前位置是否合理,如果合理,继续下一层的工作,即移动模块1。直到模块2不具备移动位置,则搜索结束。下面为实际操作:

3 _ _ _ 3
2 _ _ 2
1 _ 1
找到方案1 : 231213

3 _ _ _ 3
2 _ _ 2
1 _ 1
找到方案2: 312132

你还是可以继续移动模块,但是找不到可能的有效位置了,所以以上两个解为 112233 的两个解.

对于11223344, 方法是一样的.




----------------解决方案--------------------------------------------------------

先问一句:楼主是否只找如你举例的那种规律的一组解?


----------------解决方案--------------------------------------------------------

这个题目不是我出的, 具体结果如何我也不知道, 我只找到了1组,恐怕是符合要求的解都算吧


----------------解决方案--------------------------------------------------------
12楼的我赞同,期待更好的方法
----------------解决方案--------------------------------------------------------
哈,根据kai的方法我又想到了一个方法,本质上好象是一样的
以112233为例
把1记为101,2记为1001,3记为10001,解方程
10X*101+10Y*1001+10Z*10001=111111(XYZ为10的指数,结果只能有1不能有0,所以结果只能是111111)
即可得答案X=1,Y=2,Z=0,和X=1,Y=0,Z=2,
以X=1,Y=2,Z=0为例 从右到左,以第一个数为参考点,第一个1要往左移动1位,第一个2要往左边移动2位,第一个3要往左移动0位,即右边第一个数是3,得到
_ _ _213,根据题中规律就可得结果 231213

[此贴子已经被作者于2006-5-20 23:51:33编辑过]


----------------解决方案--------------------------------------------------------

楼主我写个输入任何一数可以排序的,不过好象5排不出来,你的程序5能排出来?


----------------解决方案--------------------------------------------------------

我也没找出5的排序..不过感觉应该有

楼主看看能不能找出5的排序~!


----------------解决方案--------------------------------------------------------

看看这个
[CODE]
#include "stdio.h"
#include "malloc.h"

int main()
{
int *array,data,i,j,k;

printf("please input data:\n"); /*输入一个自然数,例如8*/
scanf("%d",&data);
if(data <= 2||data==5||data==6||data>8) /*这些没法排的*/
exit(-1);
array=(int *) malloc ( sizeof(int)*2*data);

for(i=2*data-1,j=(data+1)/2;j <= data;i--,j++)
array[i]=array[i-j-1]=j;
k=j=i-j+1;
for(i=0;i<k && k>0;i++,j++)
array[i]=array[i+j+1]=j;
array[i+j+1]=array[i+j+3]=1;

for(i=0;i<2*data;i++) /*结果两个,正序,倒序*/
printf("%d ",array[i]);
printf("\n");
for(i=2*data-1;i>=0;i--) /*两结果其实一样的*/
printf("%d ",array[i]);

free(array);
return 0;
}


[/CODE]

[此贴子已经被作者于2006-5-21 0:35:07编辑过]


----------------解决方案--------------------------------------------------------

和12楼16楼的基本想法查不多,但由于可能的顺序太多,如果不找到特殊的规律算法复杂度就是N!量级。算到12后就很慢了。
很多数没有解。

程序代码:

#include <stdio.h>
#include <malloc.h>


struct Link
{
int intValue;
struct Link * next;
};

struct LinkList
{
Link * head;
};


bool GenerateSequence(int intCurrentNumber, int intMaxNumber, LinkList *list, bool *pbAnswer);
bool ValidateSequence(LinkList *list, int intMaxNumber);

int main()
{
int intMax;
bool bAnswer;
LinkList list;
list.head = NULL;

for (intMax = 3; intMax < 13; intMax++)
{
bAnswer = false;
printf(\"Solution for %d: \", intMax);
GenerateSequence(1, intMax, &list, &bAnswer);
if (!bAnswer)
printf(\"No solution\n\");
}
return 0;
}


bool GenerateSequence(int intCurrentNumber, int intMaxNumber, LinkList *list, bool *pbAnswer)
{
int intInsertPosition;
struct Link *linkInsert;

// insert new link to list
for (int intPosition = 0; intPosition < intCurrentNumber; intPosition++)
{
// duplicate the linklist first.
struct LinkList listCurrent;
struct Link *linkCurrent, *linkCurrentLast, *linkTmp = list->head;
listCurrent.head = NULL;

if (*pbAnswer)
return true;

while (linkTmp != NULL)
{
linkCurrent = (struct Link *)malloc (sizeof(struct Link));
linkCurrent->intValue = linkTmp->intValue;
linkCurrent->next = NULL;

if (listCurrent.head == NULL)
listCurrent.head = linkCurrent;
else
linkCurrentLast->next = linkCurrent;
linkCurrentLast = linkCurrent;

linkTmp = linkTmp->next;
}

linkCurrent = (struct Link *)malloc (sizeof(struct Link));
linkCurrent->intValue = intCurrentNumber;
linkCurrent->next = NULL;

// if the first one, insert to the head
if (intPosition == 0)
{
linkCurrent->next = listCurrent.head;
listCurrent.head = linkCurrent;
}
else
{
// else insert after the number intPosition
for (linkInsert = listCurrent.head, intInsertPosition = 1; intInsertPosition < intPosition; linkInsert = linkInsert->next, intInsertPosition++)
;

linkCurrent->next = linkInsert->next;
linkInsert->next = linkCurrent;
}

if (intCurrentNumber < intMaxNumber)
GenerateSequence(intCurrentNumber+1, intMaxNumber, &listCurrent, pbAnswer);
else if (ValidateSequence(&listCurrent, intMaxNumber))
{
*pbAnswer = true;
}

// FreeListMemory
while (listCurrent.head != NULL)
{
linkCurrent = listCurrent.head;
listCurrent.head = linkCurrent->next;
free(linkCurrent);
}
}
return true;

}

bool ValidateSequence(LinkList *list, int intMaxNumber)
{
int intCount, intarNumbers[100], intPosition;
Link *linkCurrent;

if (!list)
return false;

for (intCount = 0; intCount < intMaxNumber*2; intCount++)
intarNumbers[intCount] = 0;

for (intCount = 0, linkCurrent = list->head;
linkCurrent; intCount++, linkCurrent = linkCurrent->next)
{
intPosition = intCount;
while (intarNumbers[intPosition] > 0)
intPosition ++;
intarNumbers[intPosition] = linkCurrent->intValue;

if (intarNumbers[intPosition + linkCurrent->intValue + 1] > 0)
return false;
else if (intPosition + linkCurrent->intValue + 1>= intMaxNumber * 2)
return false;

intarNumbers[intPosition + linkCurrent->intValue + 1] = linkCurrent->intValue;
}

for (intCount = 0; intCount < intMaxNumber*2; intCount++)
printf(\"%d \", intarNumbers[intCount]);
printf(\"\n\");
return true;
}



[此贴子已经被作者于2006-5-21 9:34:33编辑过]


----------------解决方案--------------------------------------------------------
  相关解决方案