这是我制作程序的问题
阿里巴巴在四十个小偷身上做了一招,并且能够抓住他们 在一个大洞穴里面,它是野狼的家。小偷是 没有任何武器,只有盗贼的长官才有刀。没有 武器他们将无法与狼战斗,所以他们决定 自杀而不是被活活吃掉。他们都决定他们会站成一个圆圈而他们每三分之一 人会杀了自己,但盗贼的首领不喜欢 这个想法并没有打算自杀。他计算在哪里 他应该站起来,以便他是最后一个离开的人。
HackerMan希望基于这个故事构建游戏,而不是 杀死他决定参与者将离开游戏,并且 而不是每个第3个位置,它将是每个第2个位置。当然 在这场比赛中,参赛人数将远远超过40人。
输入
第一行输入是整数N(1 <= N <= 1000) 指定测试用例的数量。之后每行包含一个 整数X(5 <= X <= 100000000),它是参与者的数量 游戏。
输出
对于每个测试用例,生成一个包含该位置的行 幸存的参与者。假设参与者有序列号 数字从1到n并且计数从人1开始,即, 第一个离开的人是2号人。
示例输入
3 5 11 45
示例输出
3 7 27
这是我的解决方案程序
class SurvivalStrategy {
public int next;
public int value;
public boolean alive;
SurvivalStrategy(int n, int v)
{
this.next = n;
this.value = v;
this.alive = true;
}
public int getNext(){
return this.next;
}
public void kill(){
this.alive = false;
}
public void changeNext(int n){
this.next = n;
}
public static void main(String[] args) throws IOException {
System.out.println("Enter the number of cases");
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String line = br.readLine();
int N = Integer.parseInt(line);
int[] array = new int[N];
for(int a = 0; a < N; a++)
{
System.out.println("Enter No. of theives in case " + (a + 1));
array[a] = Integer.parseInt(br.readLine());
}
for(int b = 0; b < N; b++)
{
try{
int theives = 0;
theives = array[b];
SurvivalStrategy[] people = new SurvivalStrategy[theives];
int i = 0;
int nextctr = 2;
for(i = 0; i < people.length; i++)
{
people[i] = new SurvivalStrategy(nextctr, i + 1);
if(nextctr > people.length)
{
people[i] = new SurvivalStrategy(1, i + 1);
}
nextctr++;
}
int k = 0;
int nextguy = 0;
int survivers = people.length;
boolean CarryOnJatta = true;
int lastSurviver = 0;
while(CarryOnJatta)
{
if(k >= people.length)
{
k = 0;
k = k + 2;
}
if(people[k].alive)
{
//System.out.println(people[k].value + " is Alive");
nextguy = people[k].getNext();
if(people[nextguy - 1].alive)
{
people[nextguy - 1].kill();
people[k].changeNext(people[nextguy - 1].next);
lastSurviver = people[k].value;
survivers--;
}else{
k = k + 2;
}
k = k + 2;
}else{
k = k + 2;
}
if (survivers == 1)
{
CarryOnJatta = false;
System.out.println("" + lastSurviver);
}
}
} catch(Exception e)
{
e.printStackTrace();
}
}
}
}
我的程序为小值提供输出,但不为大值输出。 如果我尝试输入(23987443)我得到Java堆大小超过错误。 有什么方法可以改善这个节目的空间和时间复杂性。 如果他们正在生成所需的输出,我也可以使用其他算法。
答案 0 :(得分:3)
你在堆上分配至少23987443 * sizeof(SurvivalStrategy)内存 - 每个案例大约300MB,这只是在这行代码之前:
SurvivalStrategy[] people = new SurvivalStrategy[theives];
我想挑战的目的是教你高效的内存处理 - 所以不要一次分配整个内存,而是需要逐个处理你的项目,这样你一次只能分配几个项目,让GC收集不再需要的那些。
答案 1 :(得分:0)
您可以尝试为JVM分配更多内存,最近有一篇关于此的帖子: Java Heap Space error from command line
答案 2 :(得分:0)
你可以使用循环LinkedList。将节点添加到列表中,并使用计数算法遍历列表。每当有人输了,只需在该人身上调用一个删除,这将标记它有资格进行垃圾收集(假设该列表包含您节点的唯一引用)。
更好的是,无需在列表的第一个周期中一次性添加所有人。如果它们是V迭代的倍数,您就不能添加某人。这应该会大大减少你的内存使用量。
这将节省堆上的空间,因为您维护的最大大小为N,但会有更多的分配/释放开销。仍然,linkedList.remove提供O(1)复杂性。我认为它会清理你的代码并使其更容易理解