Array T[] has been used to store the sum of all possible contiguous combinations. And at each step, I am checking whether it is atleast k or not and that value is stored in the variable val. Below is the Java Code:
import java.util.Arrays;
import java.util.Scanner;
class Codechef {
public static void main(String[] args) throws java.lang.Exception {
Scanner sc = new Scanner(System.in);
long t = sc.nextLong();
while (t > 0) {
int n = sc.nextInt();
long k = sc.nextLong();
long p = sc.nextLong();
long a[] = new long[n];
long T[] = new long[((n * (n + 1)) / 2)];
Arrays.fill(T, -1);
long sum = 0, x = 0, val = p, f = 0;
int i = 0;
for (i = 0; i < n; i++) {
a[i] = sc.nextLong();
sum = sum + a[i];
x = sum % p;
T[i] = x;
if (T[i] == k)
f = 1;
else if (T[i] > k && T[i] < val)
val = T[i];
}
if (f != 1) {
for (int j = i - 1; j > 0; j--) {
for (int m = 0; m < j; m++) {
x = T[j] - T[m];
if (x < 0)
x += p;
T[i] = x;
if (T[i] == k) {
f = 1;
break;
}
else if (T[i] > k && T[i] < val)
val = T[i];
i++;
}
if (f == 1)
break;
}
}
if (f == 1)
System.out.println(k);
else
System.out.println(val);
t--;
}
}
}
The above is the code for PARTSUM- Partial Sums on SPOJ. What could be the possible error?
Previously I was getting Runtime error NZEC on submit. Now that has been corrected and now I am getting TLE. Any optimization?
Related
I have a factorial function on my program that works fine until i try to execute the function deleteRepeated(), the console is telling me that the error is in the return of the factorial function, maybe it's being called by a single function too many times in a short period of time? I've been stuck for hours.
import java.util.Scanner;
public class ex9 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int[] arr = new int[n];
for (int i = 0; i < n; i++) {
arr[i] = sc.nextInt();
}
int[] newArr = new int[n - repeated(arr)];
int[] finalArr = deleteRepeated(arr, newArr);
for (int a : finalArr) {
System.out.println(a);
}
}
public static long factorial(int n) {
if (n == 0)
return 1;
return (n * factorial(n - 1));
}
public static int repeated(int arr[]) {
int n = arr.length;
int mix = (int) (factorial(n) / (2 * factorial(n - 2)));
int i = 0;
int k = 0;
int rep = 0;
int a = -100;
while (i < mix) {
for (int j = k + 1; j < n; j++) {
if (arr[k] == arr[j] && a != j) {
a = j;
rep += 1;
}
i++;
}
k++;
}
return rep;
}
public static int[] deleteRepeated(int arr[], int newArr[]) {
int n = arr.length;
int rep = repeated(arr);
int i = 0;
int k = 0;
int a = -100;
while (i < newArr.length) {
for (int j = k + 1; j < n; j++) {
if (arr[k] == arr[j] && a != arr[k]) {
a = arr[j];
newArr[k] = arr[k];
}
i++;
}
k++;
}
rep = repeated(newArr);
if (rep > 0) {
int[] newArr2 = new int[newArr.length - rep];
deleteRepeated(newArr, newArr2);
}
return newArr;
}
}
Only thing i could do to avoid the error was stopping the function from executing :/, maybe it has to do with how i'm re-calling it at the end of each execution...? is what i did allowed?
So, deleteRepeated is all messed up. The issue is deleteRepeated does not actually remove duplicate elements, so the check for the base case of recursion always fails. I'm not sure why you're using recursion here anyway; if the while loop worked properly, it could remove all duplicates without need for recursion.
It appears that you copy-pasted the implementation of repeated into deleteRepeated, and you replaced the logic for handling repeated elements with logic that handles non-repeated elements.
Here is how I would implement the method:
public static int deleteRepeated(int arr[], int newArr[]) {
int n = 0;
for(int i = 0; i < arr.length; i++) {
boolean unique = true;
for(int j = 0; j < n; j++)
unique = unique && newArr[j] != arr[i];
if(unique)
newArr[n++] = arr[i];
if(n >= newArr.length) break;
}
return n;
}
I am attempting to make an RSA algorithm and i'm not sure how to close my scanner. I have attempted to use .close(); for instance trying to place it at the end of my RSA class but to no avail. Most likley I am just not putting it in the correct place or because i keep getting the following error in Visual Studio on my line 19:
Help much appreciated.
import java.util.*;
public class RSA {
static int gcd(int m, int n) {
while (n != 0) {
int r = m % n;
m = n;
n = r;
}
return m;
}
public static void main(String args[]) {
int p = 0, q = 0, n = 0, e = 0, d = 0, phi = 0;
int nummes[] = new int[100];
int encrypted[] = new int[100];
int decrypted[] = new int[100];
int i = 0, j = 0, nofelem = 0;
Scanner sc = new Scanner(System.in);
String message;
System.out.println("Enter the Message to be encrypted:");
message = sc.nextLine();
System.out.println("Enter value of p and q\n");
p = sc.nextInt();
q = sc.nextInt();
n = p * q;
phi = (p - 1) * (q - 1);
for (i = 2; i < phi; i++)
if (gcd(i, phi) == 1) break;
e = i;
for (i = 2; i < phi; i++)
if ((e * i - 1) % phi == 0) break;
d = i;
for (i = 0; i < message.length(); i++) {
char c = message.charAt(i);
nummes[i] = c - 96;
}
nofelem = message.length();
for (i = 0; i < nofelem; i++) {
encrypted[i] = 1;
for (j = 0; j < e; j++)
encrypted[i] = (encrypted[i] * nummes[i]) % n;
}
System.out.println("\n Encrypted message\n");
for (i = 0; i < nofelem; i++) {
System.out.print(encrypted[i]);
System.out.print((char) (encrypted[i] + 96));
}
for (i = 0; i < nofelem; i++) {
decrypted[i] = 1;
for (j = 0; j < d; j++)
decrypted[i] = (decrypted[i] * encrypted[i]) % n;
}
System.out.println("\n Decrypted message\n ");
for (i = 0; i < nofelem; i++)
System.out.print((char) (decrypted[i] + 96));
return;
}
}
The problem is to generate prime in between two interval, detail problem is given in this link. SPOJ Prime Generator.
Let me explain the magic numbers and the algorithm I followed.
I have used modified Sieve Eratosthenes algorithm (modified in sense because I used the basic idea.) for implementation.
Starting number of interval, m and End number of the interval n are <= 10^9 and the difference is <=10^5 (1 <= m <= n <= 1000000000, n-m<=100000)
There is no even prime number except 2, so I considered max m and n (10^9)/2
and sqrt(max number) is around 32000 (considering both odd and even), finally 32000/2= 16,000 is the size of odd numbers list input_aray.
Finally total number range is divided into 3 regiions.
m and n both >= 32000 in this case the size of the input_aray is (n-m+1)/2 from 16001 index of array, numbers between m and n is stored (only odd numbers).
m and n <32000 in this case size of input_aray is upto n/2.
m <32000 and n>32000 in this case size of input_aray is (n-32000+1)/2.
Boolean array bol of same size as input_aray is kept to track which number is visited so that two number can't be considered twice.
for (int j = 1; j < 16001; j++) {
int flag = input_aray[j];
This loop choose n index from input_aray and check if there is any number in this array that is divisible, if so then same index of bol is initialized into false.
for (int k = j + flag; k <= 16000; k = k + flag)
This loop check for prime numbers upto 32000.
for (int k = 16001; k < input_aray.length; k++)
This one checks in between ** m and n** (when m&n >=32000)
*This is the fastest approach I could implement, but still get Time Limit Exceed. What could be the probable cause?
public static void main(String args[]){
Scanner take= new Scanner(System.in);
ArrayList<String> arrayList= new ArrayList<>();
int m,n;
int temp= take.nextInt();
take.nextLine();
if(temp>=0 && temp<=10){
for(int i=0;i<temp;i++) {
String temp1 = take.nextLine();
arrayList.add(temp1);
}
}
for(int i=0;i<arrayList.size();i++){
String[] temp_aray= arrayList.get(i).split(" ");
m= Integer.parseInt(temp_aray[0]);
n= Integer.parseInt(temp_aray[1]);
if(m>0 && n>0 && m<=10E8 && n<=10E8 && n-m<= 10E4 ) {
if (m >= 32000 && n >= 32000) {
//m & n > 32000
int start;
int[] input_aray = new int[16001 + ((n - m + 1) / 2) + 1];
boolean[] bol = new boolean[16001 + ((n - m + 1) / 2) + 1];
Arrays.fill(bol, true);
input_aray[0] = 2;
input_aray[1] = 3;
for (int j = 2; j < 16001; j++) {
input_aray[j] = input_aray[j - 1] + 2;
}
if (m % 2 == 0) {
start = m + 1;
} else {
start = m;
}
for (int j = 16001; j < input_aray.length; j++) {
input_aray[j] = start;
start += 2;
}
for (int j = 1; j < 16001; j++) {
int flag = input_aray[j];
for (int k = j + flag; k <= 16000; k = k + flag) {
if (input_aray[k] % flag == 0 && bol[k] == true) {
bol[k] = false;
}
}
for (int k = 16001; k < input_aray.length; k++) {
if (input_aray[k] % flag == 0) {
bol[k] = false;
}
}
}
int num = 1;
for (int j = 16001; j < bol.length; j++) {
if (bol[j] == true) {
System.out.println(input_aray[j]);
num++;
}
}
System.out.println();
}
if(m<32000 && n< 32000){
int[] input_aray = new int[(n/2)+1];
boolean[] bol = new boolean[(n/2)+1];
Arrays.fill(bol, true);
input_aray[0] = 2;
input_aray[1] = 3;
for (int j = 2; j < input_aray.length; j++) {
input_aray[j] = input_aray[j - 1] + 2;
}
for (int j = 1; j < Math.sqrt(n); j++) {
int flag = input_aray[j];
for (int k = j + flag; k<input_aray.length; k = k + flag) {
if (input_aray[k] % flag == 0 && bol[k] == true) {
bol[k] = false;
}
}
}
int num = 1;
for (int j = 0; j < bol.length; j++) {
if (bol[j] == true && input_aray[j] >=m && input_aray[j]<=n) {
System.out.println(input_aray[j]);
num++;
}
}
System.out.println();
}
if(m<32000 && n>32000){
int start;
int[] input_aray = new int[16001 + ((n - 32000 + 1) / 2) + 1];
boolean[] bol = new boolean[16001 + ((n - 32000 + 1) / 2) + 1];
Arrays.fill(bol, true);
input_aray[0] = 2;
input_aray[1] = 3;
for (int j = 2; j < 16001; j++) {
input_aray[j] = input_aray[j - 1] + 2;
}
start=32001;
for (int j = 16001; j < input_aray.length; j++) {
input_aray[j] = start;
start += 2;
}
for (int j = 1; j < 16001; j++) {
int flag = input_aray[j];
for (int k = j + flag; k <= 16000; k = k + flag) {
if (input_aray[k] % flag == 0 && bol[k] == true) {
bol[k] = false;
}
}
for (int k = 16001; k < input_aray.length; k++) {
if (input_aray[k] % flag == 0) {
bol[k] = false;
}
}
}
int num = 1;
for (int j = 0; j < bol.length; j++) {
if (bol[j] == true && input_aray[j]>=m && input_aray[j]<=n) {
System.out.println(input_aray[j]);
num++;
}
}
System.out.println();
}
}
}
}
I'm trying to calculate the number of rCombinations for a project for school and I can't seem to get my method to return the correct values.
I talked to my professor and he recommended canceling the common factors in factorials. Such that
35!/32! = 35*34*33.
This is what I have so far.
public static long rCombinations(int n, int r) {
int q = n-r;
long x = 1;
for(int i = r; i <= r; i ++)
{
x = n*(n-i);
}
return x/factorial(r);
}
You can use this implementation for calculating large factorial of numbers without BigInteger as follows :
import java.util.Scanner;
public class N_Faktorial {
public static void main(String[] args) {
int u = 1, A[] = new int[9999999];
Scanner scan = new Scanner(System.in);
System.out.print("n=");
int n = scan.nextInt();
A[1] = 1;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
A[j] *= i;
}
for (int j = 1; j <= n; j++) {
if (A[j] > 9) {
A[j + 1] += A[j] / 10;
A[j] %= 10;
}
if (A[u + 1] != 0) {
u++;
}
}
}
for (int i = u; i >= 1; i--) {
System.out.print(A[i]);
}
//when n>=24 count of digit of n! is equal to n+1.
System.out.println("\n Result : " + n + " count of digit " + u);
}
}
After this you need some solution for doing division operation.
Hope it helps!.
For n!/m!, where n >= m
int out = 1;
for(int i = n; i <= m; i++)
out *= i;
For n!/m!, where n <= m
double out = 1;
for(int i = n; i <= m; i++)
out /= i;
In both cases, out = n!/m!
Note that it's still easy to overflow an int, 55!/49! is too big
Compilation error in this code , how can I fix this java code?
anyone know how to fix this? and the label284; is giving some problem.
Pastebin : http://pastebin.com/gWKwnqg5
Image : http://i.imgur.com/OwbdR.png
private List<int[]> getDataByAverage()
{
int i = this.money;
Object localObject1 = new ArrayList();
if (this.num != 1)
{
for (int j = 0; j < this.num; j++)
((List)localObject1).add(new int[2]);
i /= this.num;
j = 0;
int k = 0;
while (k < this.num)
{
Object localObject2;
if (k + 1 != this.num)
{
int n;
if (10.0D * Math.random() <= 5.0D)
n = 0;
else
n = 1;
int m = (int)(Math.round(Math.random() * i) / 2L);
localObject2 = (int[])((List)localObject1).get(k);
if (n == 0)
m = i - m;
else
m = i + m;
localObject2[0] = m;
j += ((int[])localObject1.get(k))[0];
}
else
{
localObject2 = new BigDecimal(String.valueOf(this.money));
BigDecimal localBigDecimal = new BigDecimal(String.valueOf(j));
((int[])localObject1.get(k))[0] = ((BigDecimal)localObject2).subtract(localBigDecimal).intValue();
}
if (((int[])localObject1.get(k))[0] >= 0)
{
k++;
continue;
}
localObject1 = getDataByAverage();
break label284;
}
localObject1 = localObject1;
}
else
{
int[] arrayOfInt = new int[2];
arrayOfInt[0] = this.money;
((List)localObject1).add(arrayOfInt);
localObject1 = localObject1;
}
label284: return (List<int[]>)(List<int[]>)localObject1;
}
I guess labeled break is used to get out of multiple for or while loops. And you will have to declare the label above where you are using it.
you can check here
You will have to move label284: before it is used.
Might well be a method to declare a label which i am not aware of
Edit: Here's the method, put braces across the whole if (this.num != 1) else { } routine. Then define label284: before it.
Apparently the break label will goto end of statement. For more details check here
try:
private List<int[]> getDataByAverage()
{
int i = this.money;
Object localObject1 = new ArrayList();
if (this.num != 1)
{
for (int j = 0; j < this.num; j++)
((List)localObject1).add(new int[2]);
i /= this.num;
j = 0;
int k = 0;
Object localObject2;
if (k + 1 != this.num)
{
int n;
if (10.0D * Math.random() <= 5.0D)
n = 0;
else
n = 1;
int m = (int)(Math.round(Math.random() * i) / 2L);
localObject2 = (int[])((List)localObject1).get(k);
if (n == 0)
m = i - m;
else
m = i + m;
localObject2= m;
j += ((int[])((List<int[]>) localObject1).get(k))[0];
}
else
{
localObject2 = new BigDecimal(String.valueOf(this.money));
BigDecimal localBigDecimal = new BigDecimal(String.valueOf(j));
((int[])((List<int[]>) localObject1).get(k))[0] = ((BigDecimal)localObject2).subtract(localBigDecimal).intValue();
}
if (((int[])((List<int[]>) localObject1).get(k))[0] >= 0)
{
k++;
}
localObject1 = getDataByAverage();
localObject1 = localObject1;
}
else
{
int[] arrayOfInt = new int[2];
arrayOfInt[0] = this.money;
((List)localObject1).add(arrayOfInt);
localObject1 = localObject1;
}
return (List<int[]>)(List<int[]>)localObject1;
}
Declare localObject1 as a List instead of an Object. That should fix this error.