麻烦各位帮忙看看这个算法要怎么改进,谢谢!

TerryGZ 2009-05-18 05:46:52

import java.util.LinkedList;

public class lastStand {
private int stepNum = 5;
private boolean[] allStep;

public lastStand() {
}

public static void main(String[] args) {
lastStand anInstance = new lastStand();
anInstance.play();
}

private void play() {
allStep = new boolean[findIndex(stepNum-1, stepNum-1)+1];
boolean result = false;
for (int i = 0; i < stepNum; i++) {
result = takeStep(i, true);
if (result == true)
break;
}
if (result == true)
System.out.println("P1 Win");
else
System.out.println("P2 Win");
}

private void makeMove(int a, int b) {
allStep[findIndex(a, b)] = true;
}

private void unMakeMove(int a, int b) {
allStep[findIndex(a, b)] = false;
}

private int findIndex(int a, int b) {
if (a >= b)
return a * (a + 1) / 2 + b;
else
return b * (b + 1) / 2 + a;
}

private LinkedList<int[]> findStep(int lastStep) {
LinkedList<int[]> stepList = new LinkedList<int[]>();
for (int i = 0; i < stepNum; i++) {
if (!allStep[findIndex(lastStep, i)]) {
int step[] = new int[] { lastStep, i };
stepList.add(step);
}
}
return stepList;
}

private boolean takeStep(int lastStep, boolean side) {
LinkedList<int[]> stepList = findStep(lastStep);
if (stepList.isEmpty()) {
if (side)
return false;
else
return true;
} else {
boolean result = false;
while (!stepList.isEmpty()) {
int[] step = stepList.pop();
makeMove(step[0], step[1]);
result = takeStep(step[1], !side);
if (side) {
if (result == true) {
unMakeMove(step[0], step[1]);
return result;
}
} else {
if (result == false) {
unMakeMove(step[0], step[1]);
return result;
}
}
unMakeMove(step[0], step[1]);
}
return result;
}
}
}


寻路的算法,P1和P2轮流走,一次走一个step,每个step是从a走到b,a和b都是>=0和<stepNum,每个step必须是从前一个step的后一步开始,前一个人走(ab)的话后一个人就要从b开始,而且不可以重复也不可以置换,也就是说(ab)和(ba)是一样的,走过(ab)就不能再走(ba)了,找的是给出stepNum最后谁赢。因为每次都是P1先走,双方都会用最优势的走法,目标是让对手没有step可以走,所以从0开始的时候p1是有优势的。实际输入的时候有可能已经走了几步,所以输入的时候除了stepNum外还有一个字符串来表示已经走了的step,例如"(0,0)(0,1)(1,2)"就是说P1走了(0,0),P2走了(0,1),然后P1走了(1,2),这个已经走了的step是随机并合法的,所以就有了P2 win的可能,我这里只给出了当字符串为空的状况。现在的问题是当stepNum很小的时候运行结果是正确的,但stepNum>8的时候就跑不完了,而且如果是已经走了几步的话,takeStep有时候会stack overflow了,可能因为takeStep递归太多次了。麻烦各位帮忙看看有什么改进方法,完全没头绪的说,谢谢了!
...全文
142 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
绿色夹克衫 2009-05-19
  • 打赏
  • 举报
回复
剩下的点有多少是奇数不完全是靠已经走了的步决定,应当只是和N以及所走的起点和终点有关。

[Quote=引用 12 楼 TerryGZ 的回复:]
(0,0)只要没有走过的话就算合法,N是奇或偶似乎关系不大,因为剩下的点有多少是奇数是已经走了的步决定的,如果N=3,已经走了(0,0),那么0是偶1和2是奇,但如果已经走了(1,0)就变成0和1是偶2是奇了。

引用 11 楼 litaoye 的回复:
关于这道题,我想的不是很细致,我说的方法也只是和LZ共同讨论,未必是对的,不是什么正解
我所说的度为奇数就是LZ理解的意思,因为只有度为奇数的点能转化为度为1的点,而度为1的点,走入之后就…
[/Quote]
TerryGZ 2009-05-19
  • 打赏
  • 举报
回复
(0,0)只要没有走过的话就算合法,N是奇或偶似乎关系不大,因为剩下的点有多少是奇数是已经走了的步决定的,如果N=3,已经走了(0,0),那么0是偶1和2是奇,但如果已经走了(1,0)就变成0和1是偶2是奇了。

[Quote=引用 11 楼 litaoye 的回复:]
关于这道题,我想的不是很细致,我说的方法也只是和LZ共同讨论,未必是对的,不是什么正解
我所说的度为奇数就是LZ理解的意思,因为只有度为奇数的点能转化为度为1的点,而度为1的点,走入之后就没有出路了,也就是获胜了

当N为偶数的时候(如果(0,0)也算一对合法点的话),似乎只有起点的度是奇数,当N为奇数的时候,则除了起点,所有点的度都是奇数

[/Quote]
绿色夹克衫 2009-05-19
  • 打赏
  • 举报
回复
关于这道题,我想的不是很细致,我说的方法也只是和LZ共同讨论,未必是对的,不是什么正解
我所说的度为奇数就是LZ理解的意思,因为只有度为奇数的点能转化为度为1的点,而度为1的点,走入之后就没有出路了,也就是获胜了

当N为偶数的时候(如果(0,0)也算一对合法点的话),似乎只有起点的度是奇数,当N为奇数的时候,则除了起点,所有点的度都是奇数

[Quote=引用 10 楼 TerryGZ 的回复:]
还是不太明白,度为奇数的点,是指剩下可以走的步为奇数吗?如果N=6,已走的步是“(0,2)(2,3)(3,4)(4,2)”,那么2就是剩下为奇数的点,因为剩下2的合法步就只有(2,1)(2,2)(2,5),我理解对吗?但还是不太明白为何奇数有帮助。

引用 9 楼 litaoye 的回复:
哦,如果有已经走了的清单,那么就不能简单地通过N的奇偶作判断了。不过感觉还是和图的出度和入度有关系,
一旦说了一个数,那么该数对应的无向图的度将会-2,如果存在度…
[/Quote]
TerryGZ 2009-05-19
  • 打赏
  • 举报
回复
还是不太明白,度为奇数的点,是指剩下可以走的步为奇数吗?如果N=6,已走的步是“(0,2)(2,3)(3,4)(4,2)”,那么2就是剩下为奇数的点,因为剩下2的合法步就只有(2,1)(2,2)(2,5),我理解对吗?但还是不太明白为何奇数有帮助。

[Quote=引用 9 楼 litaoye 的回复:]
哦,如果有已经走了的清单,那么就不能简单地通过N的奇偶作判断了。不过感觉还是和图的出度和入度有关系,
一旦说了一个数,那么该数对应的无向图的度将会-2,如果存在度为奇数的点,那么就可以利用该点获取胜利。
我想,这道题的应当是从度最低且为奇数的点开始求解的。

[/Quote]
TerryGZ 2009-05-19
  • 打赏
  • 举报
回复
原来我理解错了你终点的意思了,还以为是最后那一步是终点呢,现在似乎有点明白了,不过知道取胜的点还是不能判断是P1还是P2赢啊。

[Quote=引用 15 楼 litaoye 的回复:]
以LZ的例子来看:如果N=6,已走的步是“(0,2)(2,3)(3,4)(4,2)”

比如从(0,2)开始,此时只有0和2是奇数,而下一对点的起始点一定是2,(2,3)此时只有0和3是奇数,不管这个序列有多长,只有起点和最后的终点是奇数
博弈到最后,感觉影响结果的就是一个奇偶问题。当N为偶数时,取胜时的终点,应该就是起点0。当N为奇数时,
除了起点之外的任何一个点都可能成为终点。

[/Quote]
绿色夹克衫 2009-05-19
  • 打赏
  • 举报
回复
以LZ的例子来看:如果N=6,已走的步是“(0,2)(2,3)(3,4)(4,2)”

比如从(0,2)开始,此时只有0和2是奇数,而下一对点的起始点一定是2,(2,3)此时只有0和3是奇数,不管这个序列有多长,只有起点和最后的终点是奇数
博弈到最后,感觉影响结果的就是一个奇偶问题。当N为偶数时,取胜时的终点,应该就是起点0。当N为奇数时,
除了起点之外的任何一个点都可能成为终点。

[Quote=引用 14 楼 TerryGZ 的回复:]
为什么?可否详细说说?

引用 13 楼 litaoye 的回复:
剩下的点有多少是奇数不完全是靠已经走了的步决定,应当只是和N以及所走的起点和终点有关。
[/Quote]
TerryGZ 2009-05-19
  • 打赏
  • 举报
回复
为什么?可否详细说说?

[Quote=引用 13 楼 litaoye 的回复:]
剩下的点有多少是奇数不完全是靠已经走了的步决定,应当只是和N以及所走的起点和终点有关。
[/Quote]
绿色夹克衫 2009-05-19
  • 打赏
  • 举报
回复
哦,如果有已经走了的清单,那么就不能简单地通过N的奇偶作判断了。不过感觉还是和图的出度和入度有关系,
一旦说了一个数,那么该数对应的无向图的度将会-2,如果存在度为奇数的点,那么就可以利用该点获取胜利。
我想,这道题的应当是从度最低且为奇数的点开始求解的。

[Quote=引用 8 楼 TerryGZ 的回复:]
这个我糊涂了,要怎么转化为欧拉图啊,而且像这类问题不是应该用博弈树么。另外只判断N的奇偶应该是不行的,至少当清单不为空的时候行不通。还有我上面漏了说明(我果然是表达能力差啊),那个清单是随机生成但绝对合法的,也就是说清单里的步不一定是最优化的,这样当N相同但清单不同的时候P1P2都有赢的可能性。
[/Quote]
TerryGZ 2009-05-19
  • 打赏
  • 举报
回复
这个我糊涂了,要怎么转化为欧拉图啊,而且像这类问题不是应该用博弈树么。另外只判断N的奇偶应该是不行的,至少当清单不为空的时候行不通。还有我上面漏了说明(我果然是表达能力差啊),那个清单是随机生成但绝对合法的,也就是说清单里的步不一定是最优化的,这样当N相同但清单不同的时候P1P2都有赢的可能性。
绿色夹克衫 2009-05-18
  • 打赏
  • 举报
回复
感觉可以转化为欧拉图的问题,判断欧拉回路。也许只判断n的奇偶,就能得出最后的结果!
ruanxuewu0120 2009-05-18
  • 打赏
  • 举报
回复
期待迷茫
TerryGZ 2009-05-18
  • 打赏
  • 举报
回复
看来是我表达能力太差了,题目是别人给的,不知道网上有没有,大概如下:P1和P2比赛一个类似接龙的游戏,规则是从N个数中(0至N-1)取两个数A和B组成一步。除了游戏刚开始第一步可以任意组合外,每一步的第一个数都必须是前一步的最后一个数,例如前一个人选了(3,4),后一个人只能选4作为他这一步的第一个数如(4,1)(4,2)等等。已经走过的步任何一方都不能再走,每一步都不能重复而且两个数的位置换位也视为同一步,例如(2,4)和(4,2)是视作同一步,如果(2,4)已经走过了的话,那么(4,2)也被视作已经走过了。每次都是P1先走,双方都会走出最优化的选择,当对方没有合法的步可以走就算赢。输入是N和已经走了的步的清单,如"(0,0)(0,1)(1,1)(1,2)"就是说P1走了(0,0)然后P2走(0,1)P1再走(1,1)P2再走(1,2),这个清单可以为空,也就是说双方都没走任何步,要求算输出最后是P1赢还是P2赢。我上面的代码只包含了清单为空的情况,因为这种情况递归得最多,N<8的运行结果是正确的,但当N=8的时候就跑不起来了,而且当清单不为空的时候有时会引起stack overflow,麻烦帮忙看看有什么可以改进的地方。
TerryGZ 2009-05-18
  • 打赏
  • 举报
回复
回楼上,实现的功能是给出stepNum找出最后是P1赢还是P2赢。
绿色夹克衫 2009-05-18
  • 打赏
  • 举报
回复
递归次数太多的话,可以用栈来模拟,LZ最好把要实现的功能详细说一下,大家一块帮忙看看!
绿色夹克衫 2009-05-18
  • 打赏
  • 举报
回复
主要还是对题目本身不是很理解(咱理解能力差也是出了名的!),是ACM么?如果可以的话,把原题的连接给贴一下吧!
TerryGZ 2009-05-18
  • 打赏
  • 举报
回复
稍微顶一下。

33,006

社区成员

发帖
与我相关
我的任务
社区描述
数据结构与算法相关内容讨论专区
社区管理员
  • 数据结构与算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧