我遇到了像这样的算法问题:
N人按某种顺序排队(他们的每个位置都标记为1 ... N。),然后执行连续的舞蹈动作,重新排序他们的位置。
用N个数字描述一组舞蹈动作,称它们为d1,d2,d3,... dn。位置i的人对应于舞蹈动作di。在舞蹈动作期间,每个人都移动到他或她的新位置。并非所有di的值都是不同的,这意味着某些人可能被放置在同一个方格上。这意味着他们将一起移动剩余的其余舞蹈。
输入:
第一行输入N(人数),下一行输入d1,d2,d3 ...... dn。
输出
无论发生多少次洗牌,我都必须输出总是包含人的位置数。
示例输入:
4
3 2 1 3
分析:
这里,N = 4且d1 = 3,d2 = 2,d3 = 1,d4 = 3
此处的输出将为 3 ,因为空格1,2和3中始终会有人。
在第一次洗牌中,第1和第4人将被映射"索引3.人2将被映射"索引1,而人3将被映射"无论这个舞蹈过程持续多少次,这三个点总是被占用,因为数字3,1,2在前三个数字中,这些是被占用的三个点。
-
我不确定这是否需要某种特殊的数据结构?也许是队列?我已经尝试了几个小时的一些想法,但我无法想出任何东西。非常感谢任何帮助。
我创建了一个整数数组[1 ... N],表示人们的原始位置,我创建了另一个数组[d1 ... dn],表示与每个索引对应的映射。通过一些研究,我找到了" multisets,"这可能是相关的。我尝试搞乱那些以及ArrayList,但我仍然无法取得很大进展。
答案 0 :(得分:1)
当前回答
前一个答案假设人们到新位置的移动是连续的,即人们会在同一序列中开始一起移动。
下面的答案假设同一序列内的运动是瞬时的。它使用两个数组将人们从旧位置映射到新位置,并且只要占用的空间总数减少,就会继续运行序列。
public static void main(String[] args) {
int numberOfPeople = 4;
int[] moves = new int[]{3, 2, 1, 3};
int[] positions = new int[numberOfPeople];
Arrays.fill(positions, 1);
int positionsOccupied;
do {
positionsOccupied = positionsOccupied(positions);
positions = dance(positions, moves);
} while (positionsOccupied(positions) < positionsOccupied);
System.out.println("Result: " + positionsOccupied(positions));
}
public static int[] dance(int[] oldPositions, int[] moves) {
int[] newPositions = new int[oldPositions.length];
for (int i = 0; i < oldPositions.length; i++) {
newPositions[moves[i] - 1] += oldPositions[i];
}
return newPositions;
}
public static int positionsOccupied(int[] positions) {
int result = 0;
for (int i = 0; i < positions.length; i++) {
if (positions[i] > 0) {
result++;
}
}
return result;
}
上一个回答
实际上,您只需要一个数组来保存positions
,另外一个数组可以保存前一个状态的snapshot
。
每次迭代后,将快照与当前位置进行比较,如果它们相等,这意味着后续的舞蹈序列调用将不会对位置产生进一步影响,并且您可以计算最终结果:
public static void main(String[] args) {
int numberOfPeople = 4;
int[] moves = new int[]{3, 2, 1, 3};
int[] positions = new int[numberOfPeople];
Arrays.fill(positions, 1);
int[] snapshot;
do {
snapshot = Arrays.copyOf(positions, positions.length);
dance(positions, moves);
} while (!Arrays.equals(positions, snapshot));
System.out.println("Result: " + positionsOccupied(positions));
}
public static void dance(int[] positions, int[] moves) {
for (int i = 0; i < positions.length; i++) {
int currentNumber = positions[i];
positions[i] = 0;
positions[moves[i] - 1] += currentNumber;
}
}
public static int positionsOccupied(int[] positions) {
int result = 0;
for (int i = 0; i < positions.length; i++) {
if (positions[i] > 0) {
result++;
}
}
return result;
}