CodeForces 750D- New Year and Fireworks Time Limit Exceeded - java

I am unable to optimise the following dynamic programming problem:
This is my JAVA solution for the problem with the following test cases.The limit gets exceeded on higher recursion levels. I am unable to understand how memoization can be implemented in this case. Any help would be appreciated.
import java.util.*;
public class ProblemD {
static class Fireworks{
boolean occupied;
int dir;
public Fireworks(boolean occupied,int dir){
this.occupied=occupied;
this.dir=dir;
}
}
public static void fireworks(Fireworks f[][],int i,int j,int levels[],int n){
if(n<levels.length){
for(int k=1;k<levels[n];k++){
if(f[i][j].dir==0){
f[i+1][j]=new Fireworks(true,0);
i=i+1;
}
else if(f[i][j].dir==45){
f[i+1][j-1]=new Fireworks(true,45);
i=i+1;
j=j-1;
}
else if(f[i][j].dir==90){
f[i][j-1]=new Fireworks(true,90);
j=j-1;
}
else if(f[i][j].dir==135){
f[i-1][j-1]=new Fireworks(true,135);
i=i-1;
j=j-1;
}
else if(f[i][j].dir==180){
f[i-1][j]=new Fireworks(true,180);
i=i-1;
}
else if(f[i][j].dir==225){
f[i-1][j+1]=new Fireworks(true,225);
i=i-1;
j=j+1;
}
else if(f[i][j].dir==270){
f[i][j+1]=new Fireworks(true,270);
j=j+1;
}
else{
f[i+1][j+1]=new Fireworks(true,315);
i=i+1;
j=j+1;
}
}
//n++;
if(f[i][j].occupied && n<levels.length-1){
if(f[i][j].dir==0){
f[i+1][j-1]=new Fireworks(true,45);
f[i+1][j+1]=new Fireworks(true,315);
fireworks(f,i+1,j-1,levels,n+1);
fireworks(f,i+1,j+1,levels,n+1);
return;
}
else if (f[i][j].dir==45){
f[i][j-1]=new Fireworks(true,90);
f[i+1][j]=new Fireworks(true,0);
fireworks(f,i,j-1,levels,n+1);
fireworks(f,i+1,j,levels,n+1);
return;
}
else if(f[i][j].dir==90){
f[i+1][j-1]=new Fireworks(true,45);
f[i-1][j-1]=new Fireworks(true,135);
fireworks(f,i+1,j-1,levels,n+1);
fireworks(f,i-1,j-1,levels,n+1);
return;
}
else if(f[i][j].dir==135){
f[i][j-1]=new Fireworks(true,90);
f[i-1][j]=new Fireworks(true,180);
fireworks(f,i,j-1,levels,n+1);
fireworks(f,i-1,j,levels,n+1);
return;
}
else if(f[i][j].dir==180){
f[i-1][j-1]=new Fireworks(true,135);
f[i-1][j+1]=new Fireworks(true,225);
fireworks(f,i-1,j-1,levels,n+1);
fireworks(f,i-1,j+1,levels,n+1);
return;
}
else if(f[i][j].dir==225){
f[i-1][j]=new Fireworks(true,180);
f[i][j+1]=new Fireworks(true,270);
fireworks(f,i-1,j,levels,n+1);
fireworks(f,i,j+1,levels,n+1);
return;
}
else if(f[i][j].dir==270){
f[i-1][j+1]=new Fireworks(true,225);
f[i+1][j+1]=new Fireworks(true,315);
fireworks(f,i-1,j+1,levels,n+1);
fireworks(f,i+1,j+1,levels,n+1);
return;
}
else {
f[i+1][j]=new Fireworks(true,0);
f[i][j+1]=new Fireworks(true,270);
fireworks(f,i+1,j,levels,n+1);
fireworks(f,i,j+1,levels,n+1);
return;
}
}
}
else{
return;
}
}
public static void main(String[] args){
Fireworks f[][];
f=new Fireworks[500][500];
for(int i=0;i<500;i++){
for(int j=0;j<500;j++){
f[i][j]=new Fireworks(false,0);
}
}
Scanner sc=new Scanner(System.in);
int start=250;
int n=sc.nextInt();
int levels[]=new int[n];
f[start][start].occupied=true;
f[start][start].dir=0;
for(int i=0;i<n;i++){
levels[i]=sc.nextInt();
}
fireworks(f,start,start,levels,0);
int count=0;
for(int i=0;i<500;i++){
for(int j=0;j<500;j++){
if(f[i][j].occupied){
System.out.println(i+" "+j);
count++;
}
}
}
System.out.println(count);
}
}

Related

How can I combine the below if loops?

I want to combine below two for loops and corresponding if-loops with break statement. How can I do that.
public class Test {
public static void main(String[] args) {
for(int i=0;i<10;i++){
if(i==2){
System.out.println("i2: "+ i);
break;
}
System.out.println("i2: "+ i);
}
for(int i=0;i<10;i++){
if(i==4){
System.out.println("i4: "+ i);
break;
}
System.out.println("i4: "+ i);
}
}
}
Try this
public class Test {
public static void main(String[] args) {
boolean 2completed = false;
boolean 4completed = false;
for(int i=0;i<10;i++){
if(i==2){
System.out.println("i2: "+ i);
2completed = true;
}
else if(i==4){
System.out.println("i4: "+ i);
4completed = true
}
if(!2completed)
System.out.println("i2: "+ i);
if(!4completed)
System.out.println("i4: "+ i);
}
}
}

the error when i change a number in decimal base to another base

I am writing a java code to Change a number from decimal base to another base.
But I don't know why the program runs wrong. I think the error comes from function Prin_as. Can anyone tell me why ?
Below is my code,
import java.util.Scanner;
public class bai2chuyendoi {
public static void main(String[] args) {
int a, b;
System.out.println("Number in decimal base:");
a = Enter();
System.out.println("Other base :");
b = Enter();
Change_base (a, b);
}
public static int Enter() {
int n = 0;
boolean check = false;
while (!check) {
Scanner sc = new Scanner(System.in);
try {
n = sc.nextInt();
check = true;
} catch (Exception e) {
System.out.println("Enter again:");
sc.nextLine();
}
}
return n;
}
public static void Change_base(int a, int b) {
int i = 0;
int[] c = new int[8];
while (a != 0) {
c[i] = a % b;
a = a / b;
i++;
}
while (i >= 0) {
--i;
if (c[i] < 10) {
System.out.print(c[i]);
} else {
System.out.print((char) (c[i] + 55));
}
}
}
}
The error was in Change_base method in second while loop.
You need decrement 'i' and check that i >= 0, but you didn't.
while (--i >= 0) {
if (c[i] < 10) {
System.out.print(c[i]);
} else {
System.out.print((char) (c[i] + 55));
}
}

"Race" appearance. How to create a consistent line length

I have created the following but need the output line to maintain a consistent width to give the appearance of a race. I also need to ensure that the racers do not slip back past the start.
Currently, the output plots correctly, but the line only extends to the racers position.
Also, when there is a "slip" it appears that the racer sometimes moves back to start. I'm not sure if that is solved with a consistent length of "race track" as well.
import java.util.*;
public class Race {
public static void main(String []args) {
int finish=70,tort=1,hare=1,rtime=0;
System.out.println("ON YOUR MARK, GET SET\nBANG !!!!!\nAND THEY'RE OFF !!!!!\n");
do{
hare=movehare(hare);
tort=movetort(tort);
print(tort,hare);
rtime++;
}
while(tort<finish&&hare<finish);
if(tort>hare ){
System.out.println("\nTORTOISE WINS!\n");
}
else if(tort<hare ){
System.out.println("\nHARE WINS!\n");
}
else{
System.out.println("IT\'S A TIE!\n");
}
}
public static void print(int t,int h){
int i;
if(h==t){
for(i=0;i<h;i++)
System.out.print("_");
System.out.println("OUCH!!!");
}
else if(h<t){
for(i=0;i<h;i++)
System.out.print("_");
System.out.print("H");
for(i=0;i<(t-h);i++)
System.out.print("_");
System.out.print("T");
}
else{
for(i=0;i<t;i++)
System.out.print("_");
System.out.print("T");
for(i=0;i<(h-t);i++)
System.out.print("_");
System.out.print("H");
}
System.out.println();
}
public static int movehare(int r ){
int num;
num=(int)(Math.random()*10);
if(num<2){
r-=2;
}
else if(num<5){
r++;
}
else if(num<6){
r-=12;
}
else if(num<8){
r+=9;
}
if(r< 1 ){
r=1;
}
return r;
}
public static int movetort(int t){
int num;
num=(int)(Math.random()*10);
if(num<5){
t+=3;
}
else if(num<7){
t-= 6;
}
else{
t++;
}
if(t<1){
t=1;
}
return t;
}
}
You can print extra "_" after each of the IF branches in your print method
if(h != t){
for(i = Math.max(h,t); i < 70; i++){
System.out.print("_");
}
}
Note: The line breaks will be off when the H == T because you print "Ouch!!!", so you'll have to check for that and accommodate.

Input Validation - Only Integers?

I'm working on a project where the Java code must find the total,
average, etc. of exam scores. It reads the scores from an external
file.
I've been trying for hours to find a way to edit my code so that it ignores any data in the file that is not an integer between 0-100. But I can't. Checked all the questions and answers on Stack Overflow, and I can't find any answers that would help my specific situation. Here's the while loop of my code that I'm trying to work with:
Scanner reader = new Scanner(file);
while (reader.hasNext())
{
String line = reader.nextLine();
nextScore = Integer.parseInt(line);
System.out.println(nextScore);
sum = nextScore + sum;
totalNumberOfScores++;
if (nextScore > maxScore)
{
maxScore = nextScore;
}
else if (nextScore < minScore)
{
minScore = nextScore;
}
if (nextScore >= A)
{
countA++;
}
else if (nextScore >= B)
{
countB++;
}
else if (nextScore >= C)
{
countC++;
}
else if (nextScore >= D)
{
countD++;
}
else
{
countF++;
}
}
reader.close();
Can anyone help ?
if(isInteger(line)){
nextScore = Integer.parse(line);
}
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
} catch(NullPointerException e) {
return false;
}
// only got here if we didn't return false
return true;
}
then you can do this
boolean isNumber = false;
for(int i = 0; i < line.length; i++){
try{
Integer.parseInt(String.valueOf(line.charAt(i)));
}catch(Exception e){
isNumber = false;
break;
}
}
if(isNumber){
Integer.parse(line);
}
or even
boolean isNumber = true;
try{
Integer.praseInt(line);
}catch(Exception e){
isNumber = false;
}
if(isNumber){
//everthing else
}
I would use a try-with-resources Statement to close the Scanner when through reading. Next, you need to define your min, max, total and lines count outside the loop. You could default min to the maximum possible value, and max to the minimum; then use Math.max(int,int) and Math.min(int,int) to set the max and min respectively. Then, you need to validate that you read an int and that is in the correct range before processing it as input. Something like,
try (Scanner reader = new Scanner(file)) {
int min = Integer.MAX_VALUE;
int max = Integer.MIN_VALUE;
int total = 0;
int lines = 0;
int countA = 0, countB = 0, countC = 0, countD = 0, countF = 0;
while (reader.hasNextLine()) {
String line = reader.nextLine();
try {
int nextScore = Integer.parseInt(line);
if (nextScore >= 0 && nextScore <= 100) {
min = Math.min(nextScore, min);
max = Math.max(nextScore, max);
total += nextScore;
lines++;
if (nextScore >= A) {
countA++;
} else if (nextScore >= B) {
countB++;
} else if (nextScore >= C) {
countC++;
} else if (nextScore >= D) {
countD++;
} else {
countF++;
}
}
} catch (NumberFormatException nfe) {
}
}
System.out.printf("Min: %d, Max: %d, Total: %d, Lines: %d, Average: %.2f%n",
min, max, total, lines, total / (float) lines);
System.out.printf("%d As, %d Bs, %d Cs, %d Ds, %d Fs", countA, countB,
countC, countD, countF);
} catch (IOException e) {
e.printStackTrace();
}

char array to int array conversion in java generates null pointer exception

I am trying to run the following HillCipher program but it is terminated after the line of conversion of char array to int array and after compilation of that code it shows me null pointer exception.It works fine if I replace int array with int variable,but I need int array in this code to encrypt the data:
try{
do//key
{
System.out.println("Enter Key of length 4 character : ");
sKey=(new BufferedReader(new InputStreamReader(System.in))).readLine();
cKey=new char[2][2];
}while(!checkKey());
}
catch(Exception e)
{}
}
boolean checkKey()
{
boolean flag=true;
if(sKey.length()!=4)
flag=false;
int k=0;
int temp;
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
cKey[i][j]=sKey.charAt(k);
k++;
iKey[i][j]=(int)cKey[i][j]; //program is terminated after this line
iKey[i][j]-=97;
if(cKey[i][j]<97 || cKey[i][j]>122)
{
flag=false;
break;
}
}
if(flag==false)
{
System.out.println("flag: "+flag);
break;
}
}
int d;
if((d=iKey[0][0]*iKey[1][1]-iKey[1][0]*iKey[0][1])==0)
flag=false;
if(flag==false)
System.out.println("Invalid Key!! ");
else
keygen(d);
return flag;
}
void keygen(int d)
{
if (d<0)
d*=-1;
for(int i=0;i<2;i++)
{
for(int j=0;j<2;j++)
{
if(i==0 && j==0)
iDKey[i][j]=iKey[1][1]/d;
else if(i==1 && j==1)
iDKey[i][j]=iKey[0][0]/d;
else
iDKey[i][j]=-iKey[i][j]/d;
}
}
}
String encrypt()
{
int l;
if(sPlainTxt.length()%2==0)
l=sPlainTxt.length();
else
l=sPlainTxt.length()+1;
int temp1,temp2,ans;
for(int i=0;i<l;i+=2)
{
temp1=(int)cPlainTxt[i]-97;
temp2=(int)cPlainTxt[i+1]-97;
ans=iKey[0][0]*temp1+iKey[0][1]*temp2;
System.out.println(ans);
ans%=26;
ans+=65;
cCipherTxt[i]=(char)ans;
cCipherTxt[i+1]=(char)((iKey[1][0]*temp1+iKey[1][1]*temp2)%26+65);
}
sCipherTxt=new String(cCipherTxt);
return sCipherTxt;
}
}
You never assign a value to iKey, so it has its initial default value of null - it's as simple as that. You need to create a new array, e.g.
// Given that you've hard-coded the length of cKey as well...
iKey = new int[2][2];
I'd also strongly urge you not to catch exceptions like this:
catch(Exception e)
{}

Categories