Problem
Turtles live long (and prosper). Turtles on the island Zanzibar are
even immortal. Furthermore, they are asexual, and every year they give
birth to at most one child. Apart from that, they do nothing. They
never leave their tropical paradise.
Zanzi Bar, the first turtle on Zanzibar, has one further activity: it
keeps track of the number of turtles on the island. Every New Year’s
Day it counts the turtles, and writes the total number in a small
booklet. After many years this booklet contains a non-decreasing
sequence of integers, starting with one or more ones. (After emerging
from its egg on Zanzibar’s beautiful beach, it took Zanzi some time to
start a family on its own.)
One day Zanzi realizes that it could also be the case that turtles
from abroad come to Zanzibar, by boat or plane. Now it wonders how
many of the inhabitants were not born on Zanzibar. Unfortunately, it
can only derive a lower bound from the sequence in the booklet.
Indeed, if the number of turtles in a year is more than twice as big
as the year before, the difference must be fully explained by import.
As soon as Zanzibar has 1000000 turtles, the island is totally covered
with turtles, and both reproduction and import come to a halt. Please
help Zanzi! Write a program that computes the lower bound of import
turtles, given a sequence, as described above.
Input
The input starts with a line containing an integer T(1≤T≤13), the
number of test cases. Then for each test case:
One line containing a sequence of space-separated, positive integers
(≤1000000), non-decreasing, starting with one or more ones. For
convenience, a single space and a 0 are appended to the end of the
sequence.
Output
For each test case, output a line containing a single integer: the
lower bound for the number of turtles not born on Zanzibar.
See question and sample input and output here
My approach
public Zanzibar() {
Scanner scan = new Scanner(System.in);
int iterations = scan.nextInt();
for (int i = 0; i < iterations; i++) {
int previous = -1;
int current = -1;
int lower = 0;
while (true) {
if (current != -1)
previous = current;
current = scan.nextInt();
if (current == 0)
break;
if (current > 2 * previous && previous != -1)
lower += current - previous;
}
System.out.println(lower);
}
}
I think I am understanding the problem wrong. Am I supposed to keep adding to the lower bound or should I find the biggest difference between two years? Also I don't understand how input 1 100 0 produces output 98 (from the link). Shouldn't it be 99?
This is what the problem setter wants us to understand:
The initial 1 for every test case means that the initial population on the island is always 1
So for an input like 1 1 1 0, it means that:
The initial population is 1. Then at the start of the 2nd year, the population is still 1. At the start of the 3rd year, the population is still 1.
As for your doubt about the input: 1 28 0, it means that:
At the start of the 2nd year, the population is 28, whereas the maximum that could have been is 2, as the only turtle could have given birth to one more turtle at max. So, it means that clearly, at least (28-2) = 26 turtles migrated!!!
Hope it helps...
Edit: This is the algorithm:
For every line of test case do the following:
Set initial to 1, migrated to 0
Start reading from the second number in the line, until we encounter a 0:
If the current number is greater than 2*initial: migrated = migrated + (current - 2*initial)
Else: do nothing
Set initial to current
Print migrated
Edit-2:
Here is the JAVA implementation:
import java.util.*;
class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int iterations = scan.nextInt();
int i = 0;
int len,x;
int j,initial;
long migrated;
int arr[] = new int[1000005];
while(i<iterations)
{
len = 0;
while(true)
{
x = scan.nextInt();
if(x==0)
break;
arr[len++] = x;
}
initial = arr[0];
migrated = 0;
j = 1;
while(j<len)
{
if(arr[j]-(2*initial)>0)
{
migrated += arr[j]-(2*initial);
}
initial = arr[j];
j++;
}
System.out.println(migrated);
i++;
}
}
}
Input:
3
1 100 0
1 1 1 2 2 4 8 8 9 0
1 28 72 0
Output:
98
0
42
Related
In this lab, you will be creating a program that merges two arrays of positive (greater than 0) integers. Your program will accept each array as input from the keyboard. You do not know ahead of time how many values will be entered, but you can assume each array will have a maximum length of 10,000 elements. To stop entering values enter zero or a negative number. You should disregard any non-positive numbers input and not store these in the array.
The elements of the two input arrays should be in increasing order. In other words, each array element must have a value that is greater than or equal to the previous element value. An array may contain repeated elements.
After the two arrays have been input, your program must check to make sure the elements of each array have been entered in order. If an out of order element is found, print the message “ERROR: Array not in correct order”.
Your task is to merge the two input arrays into a new array, with all elements in order, lowest to highest. Print out each of the original arrays entered, followed by the merged array.
Please note that your program must output the arrays with exactly one space between each of the numbers.
Sample Run 1:
Enter the values for the first array, up to 10000 values, enter zero or a negative number to quit
3
3
5
6
8
9
-1
Enter the values for the second array, up to 10000 values, enter zero or a negative number to quit
3
4
5
6
-5
First Array:
3 3 5 6 8 9
Second Array:
3 4 5 6
Merged Array:
3 3 3 4 5 5 6 6 8 9
My code was:
import java.util.Scanner;
class Main{
public static void main(String[] args)
{
Scanner scan = new Scanner(System.in);
int one1=0;
int two1=0;
int a = 0;
int b = 0;
int flag = 0;
int[]one=new int[10000];
int[]two=new int[10000];
System.out.println("Enter the values for the first array, up to 10000 values, enter a negative number to quit");
while (a==0){
int first = scan.nextInt();
if (first<=0) a++;
else{
one[one1]=first;
one1++;
}
}
System.out.println("Enter the values for the second array, up to 10000 values, enter a negative number to quit");
while (b==0){
int second = scan.nextInt();
if (second<=0) b++;
else{
two[two1]=second;
two1++;
}
}
System.out.println("First Array:");
for (int i = 0 ; i < one1 ; i++){
System.out.print(one[i]+" ");
}
for (int i = 0 ; i < one.length-1 ; i++){
if (one[i]>one[i+1]) flag++;
}
System.out.println("Second Array:");
for (int i = 0 ; i < two1 ; i++){
System.out.print(two[i]+" ");
}
for (int i = 0 ; i < two.length-1 ; i++){
if (two[i]>two[i+1]) flag++;
}
int[]combo = new int[one.length+two.length];
for (int i = 0 ; i < combo.length-1 ; i+=2){
combo[i]=one[i];
combo[i+1]=two[i];
}
if (flag>0) System.out.println("ERROR: Array not in correct order");
else{
for (int i = 0 ; i < combo.length; i++){
System.out.print(combo[i]+" ");
}
}
}
}
This code keeps giving me runtime error- what am I doing wrong?
I am sorry, your merge algortithm is all wrong. You create an array combo of length one.length + two.length, that is, 20000 (I think one1 + two1 should suffice). Then you try to fill the new array by looping through it two elements at a time:
for (int i = 0; i < combo.length - 1; i += 2) {
So i is 0, 2, 4 etc. through 19998 (the last even number before 20000). Except when it gets 10000, you try to pick out one[i], that is one[10000], which is outside the one array. This gives the ArrayIndexOutOfBoundsException.
How I found out? The stack trace gives a line number. The line it mentions is
combo[i] = one[i];
It also mentioned the number 10000, so I knew this was the value of i at this point.
I think that what you were trying to do, was fill elements 0 from one and two into elements 0 and 1 of combo, I think it works so far. Then you wanted to fill element 1 from each array into elements 2 and 3; but since you have added 2 to i, you fill in element 2 from each source array and never use element 1 from them. Or any element from odd indices.
Before you mend that problem, allow me to mention one more thing. I think with your logic, input arrays 2 5 and 11 30 will come out as 2 11 5 30. This doesn’t fulfil “with all elements in order, lowest to highest”. So I think you should think your algorithm over.
the code exist many logic error,
as for Runtime Error Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10000 at..
the problem is here:
for (int i = 0 ; i < combo.length-1 ; i+=2){
combo[i]=one[i];
combo[i+1]=two[i];
}
the i from 0 to 19999 and the index of a,b is from 0 to 9999, and the code exist other simple logic problem. Please check it again.
Homework questions are very frowned upon, but still, Java is a relatively easy language. If your program is throwing a RuntimeException, you just have to read what the problem is.
In this case, it seems a loop iterates more times than it should, and you are accessing other memory space. Give it a few reads with the info provided by the error trace in mind.
Lukáš really likes orienteering, a sport that requires locating control points in rough terrain. To entertain the NWERC participants Lukáš wants to organize an orienteering race. However, it would be too harsh for the participants to be outdoors in this cold Swedish November weather, so he decided to jump on the new trend of indoor races, and set the race inside the B building of Linköping University.
Lukáš has already decided on the locations of the control points. He has also decided on the exact length of the race, so the only thing remaining is to decide in which order the control points should be visited such that the length of the total race is as he wishes. Because this is not always possible, he asks you to write a program to help him.
Input Format
The input consists of:
one line with two integers n (2 ≤ n ≤ 14) and L (1 ≤ L ≤ 1015), the number of control points and the desired length of the race, respectively;
n lines with n integers each. The jth integer on the ith line, dij , denotes the distance between control point i and j (1 ≤ dij ≤ L for i 6= j, and dii = 0). For all 1 ≤ i, j, k ≤ N it is the case that dij = dji and dij ≤ dik + dkj .
Output Format
Output one line with “possible” if it is possible to visit all control points once in some order and directly return to the first one such that the total distance is exactly L, and “impossible” otherwise.
Sample Input
3 5
0 1 3
1 0 3
4 1 0
Sample Output
possible
The problem with the code is that the for loop in else loop of function checkscenario() only considers the first iteration and returns false as a result. It doesn't check the next iteration which will return true and thus give the proper solution.
Lets use the sample input for the explanation. Initially, the function gets value of the parameters as follows :-
controlptsleft = {0,1,2,3}
//These are the control pts which haven't been visited.
index = 0;
//This is the control pt that I am at.
controlmatrix =
0 1 3
1 0 3
4 1 0
L = 5
//The desired length.
sum = 0
//Till now we haven't trailed the control pts. So, sum = 0.
public static boolean checkscenario(ArrayList<Integer> controlptsleft, int index, int[][] controlmatrix, int L, int sum){
int row = controlptsleft.get(index);
//row stores the value in the ArrayList controlptsleft at the index.
controlptsleft.remove(index);
//The controlpt is removed. The first time 0 will be removed from arrayList controlptsleft.
if(controlptsleft.isEmpty()){
//When the ArrayList controlptsleft is empty, we have to go back to the first controlflag.
int temp = controlmatrix[row][0];
//temp stores the distance between the control flag where we are at and the starting control flag.
if(L == (sum + temp))
return true;
}
else{
for(int i=0;i<controlptsleft.size();i++){
int temp = controlmatrix[row][controlptsleft.get(i)];
//temp stores the distance between the control flag where we are at and the whatever controlflag we get during the iteration.
ArrayList<Integer> tempList = controlptsleft;
boolean finalres = checkscenario(tempList,i,controlmatrix,L,(sum + temp));
//Here, i is sent so that when it enters the function again the index i (along with the value) in ArrayList tempList will be deleted.
if(finalres)
return true;
}
}
return false;
}
Just in case someone out there wants to know, I figured out the answer for this challenge.
First of all, i would like to thank Hanno Binder for that comment. I realized where I went wrong.
Inside the else loop of the function checkscenario
else{
for(int i=0;i<controlptsleft.size();i++){
int temp = controlmatrix[row][controlptsleft.get(i)];
ArrayList<Integer> tempList = controlptsleft;
boolean finalres = checkscenario(tempList,i,controlmatrix,L,(sum + temp));
if(finalres)
return true;
}
What I did was, I directly copied the reference of controlptsleft to tempList. I realized the bug and I instead initialized tempList and used .addAll to put all the values from controlptsleft to tempList.
The following code illustrates what I meant above.
else{
for(int i=0;i<controlptsleft.size();i++){
int temp = controlmatrix[row][controlptsleft.get(i)];
ArrayList<Integer> tempList = new ArrayList<Integer>();
tempList.addAll(controlptsleft);
boolean finalres = checkscenario(tempList,i,controlmatrix,L,(sum + temp));
if(finalres)
return true;
}
}
If someone has a better solution in JAVA for the challenge mentioned above. Feel free to post their code, so I could learn how to code better.
I am trying to find a way to count down from the int that is input by a user and then add each second value as i count down to 0
for example.
{user inputs 10
program counts down 8,6,4,2,0
then add 10 + 8 + 6 + 4 +2 +0= 30
}
how can I do this using a nested for loop
so far I have only been able to take user input, and count down by 2 each time. I get to 0 but have no way of adding every second value.
My code:
so far, it just counts to 0
public class Week5b {
static Scanner userVal = new Scanner (System.in);
public static void main(String[] args) {
//printTable();
reverseAddSkip();
public static void reverseAddSkip(){
System.out.println("Please enter an integer");
for (int i = userVal.nextInt(); i >=0; i-=2){
System.out.println(i) ;
}/* this creates a loop where the variable i is equal to user input;
the condition for the loop to continue is whether the input is larger or equal to 0; the update part of the loop takes 2 away each time, as if it were -- (which takes away one each time) */
}
}
How would I write that out mathematically?
Adding the sum of i-=2 to the original value of i.
You type 11 , it counts 9 7 5 3 1 , then adds 11 9 7 5 3 1. and give you the sum.
don't know how to sum every 2 numbers decrementing by 2, from a user value.
You input put 50, it counts down by 2 to 0
you put 51 it counts down by 2 to 0
but I haven't found away to sum all then numbers that were generated before getting to 0
:/
NoGlitching,
You need to look at the control flow of your program - which is to say, the path it takes upon execution.
You should also look at using more variables.
I'll give you the pseudocode I would use, because I think it's important for you to be able to write the code yourself:
Make a new integer called OriginalInput.
Make a new integer called RunningTotal.
Set RunningTotal to 0.
Store the user's input in OriginalInput.
Loop through OriginalInput.
Print the current OriginalInput.
Add the current OriginalInput to RunningTotal.
When the loop is finished:
Print RunningTotal.
I hope this helps.
EDIT:
// First you equalize j with i
input = userVal.nextInt();
j = i; // Put the user input in j first. for instance 11.
for (int i = input; i >=0; i-=2)
{
if (i >= 0) // If i is not below 0
{
j += i; // Add to j what i has now (everytime -2)
// put a system out print here to show what was added
// J starts as 11 and adds 9,7,5,3,1 then nothing. So it ends as 36.
}
}
// outside the For loop after it ends but INSIDE your method, you get the sum from the variable j!
I'm writing a program to read a barcode from an image which then produces an array of 1's and 0's from which I produce and array of numbers between 0-9. To do this I have to take the original array in 7 bit sequences and compare them against another array to figure out which number that pattern represents. Half way through the barcode there are 5 lines which separate the left pattern from the right pattern (which is meant to be the optical inverse of the left). I'm having problems with it catching the middle of the array and jumping ahead five spots. It's 95 bits 6 of which are the opening and closing patters and do not represent numbers and then the 5 bit pattern in the middle. I'm catching it at 45 and jumping it ahead to 50 but this isn't producing the correct results. I checked several times to make sure that these are the correct values and they seem to be but they aren't working. Here is the original set of 1s and 0s in string form:
10100110010010011011110101000110110001010111101010100010010010001110100111001011001101101100101
Here is the code num is the original array (what is above), numTemp is the current 7 bit pattern I am working with (and a subset of num).
int tempIndex = 0;
if (start == 45) {
start = 50;
}
while (start < end) {
numTemp[tempIndex] = num[start];
start++;
tempIndex++;
}
end = end + 7;
System.out.println(" ");
for (int x = 0; x < 7; x++) {
System.out.print(numTemp[x]);
}
There is a larger loop that encloses this and more but I didn't think it too relevant. Basically start starts at 3 and end starts at 10 and both keep incrementing until the larger loop has run 12 times (the number of numbers represented by the 7 bit patterns).
As you can see I print out each numTemp pattern here is the output:
>0011001
>0010011
>0111101
>0100011
>0110001
>0101111
>**1001111**
>0010010
>0100011
>1010011
>1001011
>0011011
The first 6 patterns are correct but the next pattern (in bold) should be 0111011 consequently the following patterns are incorrect.
Any help is really appreciated!
Are you sure about the bold value, cause as far as I see it in a range 50 - 57 I get 1000100, but any way this is what I came up with, maybe it will help you. I used data as a String, you can remodel it using arrays or what ever you need.
for (int i = 3; i < (CODE.length() - 3); i += 7) {
if (i == 45) {
i = 43;
} else {
printOut("line " + i + " - " + (i+7) + " = "+ CODE.substring(i, i+7));
}
}
I'm trying to solve problem #299 - Train Swapping in website UVa Online judge. The code I have works fine for independent test cases. However, when I use the sample input they provide, my program omits one of the test cases, the last one to be more specific:
Here is my code:
import java.util.Scanner;
public class Tester {
void problem(){
Scanner imput = new Scanner(System.in);
int numT =imput.nextInt();
int numL, aux, swaps=0;
int [] train = new int [50];
for (int i =0; i<numT; i++) {
numL = imput.nextInt();
for (int m =0; m< numL; m++) {
train[m]=imput.nextInt();
}
for (int j=0; j<numL; j++) {
if (train[j]>train[j+1]) {
for (int k =j; k<numL-1;k++) {
aux = train[k];
train[k]=train[k+1];
train[k+1]=aux;
swaps++;
}
}
}
System.out.println("Optimal train swapping takes "+swaps+" swaps.");
swaps = 0;
}
}
}
Example Input:
3
3
1 3 2
4
4 3 2 1
2
2 1
Example Output:
Optimal train swapping takes 1 swaps.
Optimal train swapping takes 6 swaps.
Optimal train swapping takes 1 swaps.
My code prints until the second solution, then for some reason stops. I've tried to debug it and check what's going on step by step but it has driven me to a migraine point. Any insight is highly appreciated.
...
To be more precise it stops at the second for loop the third time around without taking anything into the array...and I don't know why!
Another thing I found out is that to solve this problem the number of swaps for the case of the middle is 6, therefore the bubble sort wont be useful here, since it makes over 10 swaps thus yielding a wrong output, this is a separate issue to the original one I presented however. I still haven't figure out why it stops the third time around the loop where I assign values to the array for the third time.
The input consists of:
first line is number of cases.
this line enters the length of a train ex: 4
this line enters the number of the wagons ex: 2 4 3 1
the next following lines correspond to the following test cases whose structure is the same as the example.
They ask you to arrange the train and tell the number of swaps made to make the train in order.