英文:
How can I remove all instances of minimum values from array?
问题
我正在尝试通过在Codeforces上做一些练习问题来准备USACO Bronze,并且我已经在这个问题上挣扎了两个星期。
这是问题的要求。
起初,我正在迭代数组,删除最小元素,将长度存储在一个变量中,然后重复,直到没有值剩余。
然而,这非常低效,效果不好,所以我决定改为计算每个元素的实例数,然后从中减去。
我预期的值是8。然而,我收到的值是1,这使我认为变量值一直被重置,只打印出最后/最大实例出现的次数。
我应该如何修改我的代码,以便能够成功地从数组长度中删除最小元素的实例数,将新长度存储在变量中,并在此过程中不会重置任何值?
请原谅我如果这是一个非常愚蠢的问题,因为我刚刚开始USACO,而且我还不习惯竞技编程。
public class sort {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// System.out.println("PLEASE INSERT AN ELEMENT");
int x = sc.nextInt();
int memory[];
memory = new int[x];
for (int i = 0; i < x; i++) {
memory[i] = sc.nextInt();
}
Arrays.sort(memory);
int k = memory.length;
int mem2[] = new int[x];
int min = memory[0];
int array[];
for (int i = 0; i < k; i++) {
countFreq(memory, k);
array = removeElements(memory, min);
k = k + array.length;
System.out.println(k);
}
System.out.println(k);
sc.close();
}
public static void countFreq(int arr[], int n) {
boolean visited[] = new boolean[n];
Arrays.fill(visited, false);
for (int i = 0; i < n; i++) {
if (visited[i] == true)
continue;
int count = 1;
for (int j = i + 1; j < n; j++) {
if (arr[i] == arr[j]) {
visited[j] = true;
count++;
}
}
}
}
public static int[] removeElements(int[] arr, int key) {
int index = 0;
for (int i = 0; i < arr.length; i++)
if (arr[i] != key)
arr[index++] = arr[i];
return Arrays.copyOf(arr, index);
}
public static int[] addX(int n, int arr[], int x) {
int j;
int newarr[] = new int[n + 1];
for (j = 0; j < n; j++)
newarr[j] = arr[j];
newarr[n] = x;
return newarr;
}
}
英文:
I'm trying to prepare for USACO Bronze by doing some practice problems on Codeforces, and I've been struggling on this one for a good two weeks.
Here's the prompt.
At first, I was iterating through the array, removing the minimum element, storing the length in a variable, and repeating until there weren't any values left.
However, that was very inefficient and was not working well, so I decided to instead count the number of instances of each element, subtract those from.
The value I expected was 8. However, the value I received was one, leading me to think the variable value keeps getting reset and it only print out the number of times the last/greatest instance occurs.
How do I modify my code so that I'm able to successfully remove the number of instances of the minimum element from the array length, store the new length in a variable and repeat this without any of my values getting reset in the process?
Please excuse me if this is a really dumb question since I'm just starting USACO, and I'm not used to competitive programming yet.
public class sort {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
// System.out.println("PLEASE INSERT AN ELEMENT");
int x = sc.nextInt();
int memory[];
memory = new int[x];
for (int i = 0; i < x; i++) {
memory[i] = sc.nextInt();
}
Arrays.sort(memory);
int k = memory.length;
int mem2[] = new int[x];
int min = memory[0];
int array[];
for (int i = 0; i < k; i++) {
countFreq(memory, k);
array = removeElements(memory, min);
k = k + array.length;
System.out.println(k);
}
System.out.println(k);
sc.close();
}
public static void countFreq(int arr[], int n) {
boolean visited[] = new boolean[n];
Arrays.fill(visited, false);
for (int i = 0; i < n; i++) {
if (visited[i] == true)
continue;
int count = 1;
for (int j = i + 1; j < n; j++) {
if (arr[i] == arr[j]) {
visited[j] = true;
count++;
}
}
}
}
public static int[] removeElements(int[] arr, int key) {
int index = 0;
for (int i = 0; i < arr.length; i++)
if (arr[i] != key)
arr[index++] = arr[i];
return Arrays.copyOf(arr, index);
}
public static int[] addX(int n, int arr[], int x) {
int j;
int newarr[] = new int[n + 1];
for (j = 0; j < n; j++)
newarr[j] = arr[j];
newarr[n] = x;
return newarr;
}
}
答案1
得分: 1
代码中的方法没有正确遵循问题描述,排序和计数操作的逻辑也不正确。
一些问题包括:
countFreq()
方法没有正确使用。它的目的是计算数组中元素的频率,但在排序过程中没有被利用。removeElements()
方法用于从内存数组中删除最小元素的出现次数,但这种方法没有正确模拟所描述的“传送”过程。- 实现的循环与问题不匹配。
- 您可以使用
Java集合
而不是原始数组。
我基于提示中传递给您的方式来完成这个问题:
Main
- 只是输入
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] redPandas = new int[n];
for (int i = 0; i < n; i++) {
redPandas[i] = scanner.nextInt();
}
scanner.close();
int seconds = sortingOperationSeconds(redPandas);
System.out.println(seconds);
}
sortingOperationSeconds
- 实际实现
public static int sortingOperationSeconds(int[] redPandas) {
Queue<Integer> firstLine = new PriorityQueue<>();
Queue<Integer> secondLine = new LinkedList<>();
for (int panda : redPandas) {
firstLine.offer(panda);
}
int seconds = 0;
while (!firstLine.isEmpty()) {
int flSize = firstLine.size();
int flSmallestId = firstLine.peek();
seconds += flSize;
for (int i = 0; i < flSize; i++) {
int currentPanda = firstLine.poll();
if (currentPanda == flSmallestId) {
secondLine.offer(currentPanda);
} else {
firstLine.offer(currentPanda);
}
}
}
return seconds;
}
让我们逐步来看:
-
小熊猫队列:
Queue<Integer> firstLine = new PriorityQueue<>(); Queue<Integer> secondLine = new LinkedList<>();
创建两个队列来表示两行红色熊猫,
firstLine
是一个PriorityQueue
,其中最小的ID始终位于队列的前端,secondLine
是一个LinkedList
,红色熊猫在从firstLine
中删除后移动到该队列中。 -
将红熊猫添加到firstLine:
for (int panda : redPandas) { firstLine.offer(panda); }
将
redPandas
数组中的所有红熊猫提供给firstLine
队列。 -
排序操作:
int seconds = 0; while (!firstLine.isEmpty()) { int flSize = firstLine.size(); int flSmallestId = firstLine.peek(); seconds += flSize; for (int i = 0; i < flSize; i++) { int currentPanda = firstLine.poll(); if (currentPanda == flSmallestId) { secondLine.offer(currentPanda); } else { firstLine.offer(currentPanda); } } }
只要
firstLine
不为空,循环就会运行。它计算firstLine
中的红熊猫数(flSize
)和firstLine
中的最小ID(flSmallestId
)。然后,它将flSize
秒添加到seconds
计数器中。内部循环逐个从
firstLine
中删除红熊猫。如果当前红熊猫的ID等于最小ID(flSmallestId
),则将该红熊猫移动到secondLine
中。否则,将其返回到firstLine
中。这个过程持续进行,直到所有红熊猫都被移动到
secondLine
中。
英文:
The approach used in the code does not follow the problem description correctly, and the logic for sorting and counting the operations is not correct.
Some problems are:
- The
countFreq()
method is not used correctly. It's meant to count the frequency of elements in an array, but it's not utilized in the sorting process. - The
removeElements()
method is used to remove occurrences of the minimum element from the memory array, but this approach does not simulate the described teleportation process correctly. - The implemented loop does not match the question.
- You can use
Java Collections
instead of primitive arrays.
I was based on the prompt you passed, and I did it this way:
Main
- Just inputs
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int[] redPandas = new int[n];
for (int i = 0; i < n; i++) {
redPandas[i] = scanner.nextInt();
}
scanner.close();
int seconds = sortingOperationSeconds(redPandas);
System.out.println(seconds);
}
sortingOperationSeconds
- Implementation itself
public static int sortingOperationSeconds(int[] redPandas) {
Queue<Integer> firstLine = new PriorityQueue<>();
Queue<Integer> secondLine = new LinkedList<>();
for (int panda : redPandas) {
firstLine.offer(panda);
}
int seconds = 0;
while (!firstLine.isEmpty()) {
int flSize = firstLine.size();
int flSmallestId = firstLine.peek();
seconds += flSize;
for (int i = 0; i < flSize; i++) {
int currentPanda = firstLine.poll();
if (currentPanda == flSmallestId) {
secondLine.offer(currentPanda);
} else {
firstLine.offer(currentPanda);
}
}
}
return seconds;
}
Let’s step by step:
-
Red Panda Queues:
Queue<Integer> firstLine = new PriorityQueue<>(); Queue<Integer> secondLine = new LinkedList<>();
Two
Queues
are created to represent the two lines of red pandas, thefirstLine
is aPriorityQueue
, where the smallest ID always stays at the front of the queue and thesecondLine
is aLinkedList
, where red pandas are moved after being removed fromfirstLine
. -
Adding Red Pandas to firstLine:
for (int panda : redPandas) { firstLine.offer(panda); }
Offers
all red pandas from theredPandas
array to thefirstLine
queue. -
Sorting Operation:
int seconds = 0; while (!firstLine.isEmpty()) { int flSize = firstLine.size(); int flSmallestId = firstLine.peek(); seconds += flSize; for (int i = 0; i < flSize; i++) { int currentPanda = firstLine.poll(); if (currentPanda == flSmallestId) { secondLine.offer(currentPanda); } else { firstLine.offer(currentPanda); } } }
While
firstLine
is not empty, the loop runs. It calculates the number of red pandas infirstLine
(flSize
) and the smallest ID infirstLine
(flSmallestId
). Then, it addsflSize
seconds to theseconds
counter.The inner loop removes red pandas from
firstLine
one by one. If the ID of the current red panda is equal to the smallest ID (flSmallestId
), that red panda is moved tosecondLine
. Otherwise, it is returned tofirstLine
.This process continues until all red pandas have been moved to
secondLine
.
答案2
得分: -1
你当前方法的主要问题是在尝试计数和删除元素时修改了原始数组memory,这会导致意外行为和不正确的结果。
不要修改原始数组,可以使用一个单独的数据结构来跟踪每个元素的出现次数,并在不改变数组的情况下移除最小元素。
import java.util.Scanner;
import java.util.Arrays;
public class Sort {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int memory[] = new int[x];
for (int i = 0; i < x; i++) {
memory[i] = sc.nextInt();
}
int min = Arrays.stream(memory).min().getAsInt();
int minCount = (int) Arrays.stream(memory).filter(num -> num == min).count();
int k = x - minCount;
while (minCount > 0) {
memory = removeElements(memory, min);
minCount = (int) Arrays.stream(memory).filter(num -> num == min).count();
k -= minCount;
}
System.out.println(k);
sc.close();
}
public static int[] removeElements(int[] arr, int key) {
return Arrays.stream(arr).filter(num -> num != key).toArray();
}
}
我们做了以下修改:
-
不使用额外的数组mem2,而是直接使用原始数组memory。
-
找到数组中的最小元素并计算其出现次数。
-
在循环中移除数组中的最小元素,直到最小元素不再出现。在每次迭代中,更新k的值,并重新计算要移除的最小元素的计数。
通过这样做,您可以避免修改原始数组并计算正确的k值,而无需重置任何值。
英文:
The main problem with your current approach is that you are modifying the original array memory while trying to count the occurrences and remove elements. This leads to unexpected behavior and incorrect results.
Instead of modifying the original array, you can use a separate data structure to keep track of the occurrences of each element and remove the minimum element without altering the array.
import java.util.Scanner;
import java.util.Arrays;
public class Sort {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int x = sc.nextInt();
int memory[] = new int[x];
for (int i = 0; i < x; i++) {
memory[i] = sc.nextInt();
}
int min = Arrays.stream(memory).min().getAsInt();
int minCount = (int) Arrays.stream(memory).filter(num -> num == min).count();
int k = x - minCount;
while (minCount > 0) {
memory = removeElements(memory, min);
minCount = (int) Arrays.stream(memory).filter(num -> num == min).count();
k -= minCount;
}
System.out.println(k);
sc.close();
}
public static int[] removeElements(int[] arr, int key) {
return Arrays.stream(arr).filter(num -> num != key).toArray();
}
}
Here's what we did:
1.Instead of using an additional array mem2, we directly use the original array memory.
2.We find the minimum element in the array and count its occurrences.
3.We remove the minimum element from the array in a loop until there are no more occurrences of the minimum element. In each iteration, we update the count of k and recalculate the count of the minimum element to be removed.
By doing this, you can avoid modifying the original array and calculate the correct value of k without resetting any values.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论