Zadanie z Inofrmatora informatyka

0

cześć, ostro przygotowuje się do Matury z informatyki ale blokuje mnie takie dosyć proste z pozoru zadanie. Otóż wszystko było by łatwe gdyby nie to że długość ciągu cyfr w ostatnim pliku jest strasznie wielka i nawet long jest za mały... Albo robię coś źle.. Podrzucam zadanie + mój kod żeby nie było że nic nie robię.
Miałem wcześniej inaczej napisaną wersję ale już za dużo zmieniałem

import java.io.File;
import java.io.FileNotFoundException;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.stream.Stream;

import static java.lang.Integer.parseInt;

/**
 * Created by Gladus on 13.03.2018.
 */
public class Main {
    static ArrayList<String> lista = new ArrayList<String>();
    static ArrayList<Long> convertedlist = new ArrayList<Long>();
    static int l1suma2 = 0, l1suma3 = 0, l1suma5 = 0, l2suma2 = 0, l2suma3 = 0, l2suma5 = 0;
    static Scanner inp = new Scanner(System.in);
    static long result = 0;
    static String s;


    public static void main(String[] args) {
        inp.toString();


        czytaj("liczby3");
    }

    static public void czytaj(String file) {
        file = file + ".txt";

        try {
            int k = 0;
            Scanner sc = new Scanner(new File(file));
            while (k < 2) {
                s = sc.nextLine();
                result = 0;
                for (Integer i=0 ; i < s.length(); i++) {
                    result = (long) (result + (s.charAt(i) - '0') * Math.pow(2, s.length() - i - 1));
                }
                System.out.println(result);
                convertedlist.add(result);

                if ((convertedlist.get(convertedlist.size() - 1)) % 2 == 0) {
                    l1suma2++;
                }
                if ((convertedlist.get(convertedlist.size() - 1)) % 3 == 0) {
                    l1suma3++;
                }
                if ((convertedlist.get(convertedlist.size() - 1)) % 5 == 0) {
                    l1suma5++;
                }


            }
            sc.close();
            System.out.println(" w pliku " + file
                    + " jest " + l1suma2 + "liczb podzielnych przez dwa" + l1suma3 + " liczb podzielnych przez 3  oraz " + l1suma5 + "Liczb podzielnych przez 5");

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
}

screenshot-20180315223048.png

1

(a + b) mod n = (a mod n + b mod n) mod n

Edit.
Usuń to Math.pow i przemyśl dlaczego jest głupie. Pominąwszy, że to nie jest główny problem tego programu.

0
import java.io.File;
import java.io.FileNotFoundException;
import java.math.BigInteger;
import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.stream.Stream;

import static java.lang.Integer.parseInt;

/**
 * Created by Gladus on 13.03.2018.
 */
public class Main {
    static ArrayList<String> lista = new ArrayList<String>();
    static ArrayList<Long> convertedlist = new ArrayList<Long>();
    static int l1suma2 = 0, l1suma3 = 0, l1suma5 = 0, l2suma2 = 0, l2suma3 = 0, l2suma5 = 0;
    static Scanner inp = new Scanner(System.in);
    static long result = 0;
    static String s;


    public static void main(String[] args) {
        inp.toString();


        czytaj("liczby3");
    }

    static public void czytaj(String file) {
        file = file + ".txt";

        try {
            int k = 0;
            Scanner sc = new Scanner(new File(file));
            while (sc.hasNextLine()) {
                s = sc.nextLine();
                result = 0;



                if (     Reszta(s,2) == 0) {
                    l1suma2++;
                }
                if (Reszta(s,3) == 0) {
                    l1suma3++;
                }
                if (Reszta(s,5) == 0) {
                    l1suma5++;
                }


            }
            sc.close();
            System.out.println(" w pliku " + file
                    + " jest " + l1suma2 + " liczb podzielnych przez dwa " + l1suma3 + " liczb podzielnych przez 3  oraz " + l1suma5 + " Liczb podzielnych przez 5");

        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
    static public int Reszta(String b, int p){
        char zero = '0';
        int dl = b.length(); //obliczenie długości zapisu liczby b
        int d = 0; //po zakończeniu obliczeń wartością d będzie
// wartość dziesiętna liczby b modulo p
// schemat Hornera modulo p
        for (int j = 0; j < dl; j++){
            int cyfra = b.charAt(j) - zero; //odzyskanie kolejnej cyfry liczby

//poczynając od najbardziej znaczącej
            d = (d*2 + cyfra) % p; //% jest operatorem modulo w C++
        }
        return d;
    }
}

Zrobiłem tak i działa :D

0

To zadanie można bardzo łatwo rozwiązać z użyciem klasy BigInteger, co prawda czas wykonania operacji nieznacznie się wydłuży, ale za to moim zdaniem kod jest bardziej przejrzysty ;)

package test;

import java.io.File;
import java.io.IOException;
import java.math.BigInteger;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) throws IOException {
	
		Scanner reader = new Scanner(new File("src\\test\\liczby3.txt"));
		
		int divisibleByTwo = 0;
		int divisibleByThree = 0;
		int divisibleByFive = 0;
		
		BigInteger zero = new BigInteger("0");
		BigInteger two = new BigInteger("2");
		BigInteger three = new BigInteger("3");
		BigInteger five = new BigInteger("5");
		
		
		while(reader.hasNextLine()) {
			
			BigInteger number = new BigInteger(reader.nextLine(),2);
			
			if(number.mod(two).equals(zero)) {
				divisibleByTwo++;
				continue;
			}
			if(number.mod(three).equals(zero)) {
				divisibleByThree++; 
				continue;
			}
			if(number.mod(five).equals(zero)) {
				divisibleByFive++;
				continue;
			}
		}
		reader.close();
	
		System.out.println("Ilość podzielnych przez 2: "+divisibleByTwo);
		System.out.println("Ilość podzielnych przez 3: "+divisibleByThree);
		System.out.println("Ilość podzielnych przez 5: "+divisibleByFive);
		
	}
}

0

//edit: w żadnym z bloków warunkowych if nie powinno być słowa kluczowego continue :P

0

Dobra na razie dodam tutaj drugie zdanie. Jak dla mnie dużo gorszę. Miałem pomysł żeby zliczyć sume wszystkich obiektów jakie są w liście i jeżeli nie są podzielnę przez 3 to odjąć albo początkowy albo końcowy tak aby suma była największy i podzielny przez 3 ale przy 500000 wartości listy mi świrują i nie wiem w sumie jak to wykonać.screenshot-20180319010245.png



import java.io.File;
import java.io.FileNotFoundException;
import java.lang.reflect.Array;
import java.util.*;

import static java.lang.Integer.parseInt;
import static jdk.nashorn.internal.objects.Global.print;

/**
 * Created by Gladus on 18.03.2018.
 */
public class Main {
    public static void main(String[] args) {
        int sumaPoczatkowa=0;
        int sumaKoncowa=0;
        int number;
        List<Integer> zbior = new ArrayList<>(10000000);
        int i = 0;

        try {
            Scanner sc = new Scanner(new File("bloki3.txt"));
            number = parseInt(sc.next());

            while (sc.hasNextLine()) {

                try {
                    if (sc.hasNext()) {
                        number = parseInt(sc.next());

                    } else {
                        break;
                    }

                } catch (NumberFormatException e) {
                    System.out.println("error");
                }
                zbior.add(number);

            }
            long sum = zbior.stream().mapToInt(Integer::intValue).sum();

            System.out.println(sum);
            if (sum % 3 == 0) {
                System.out.println("brak usunieńć");
                System.out.println(zbior.size());
            } else {
                System.out.println("o 2 za dużo.");

                for (i =0;i<100000;i++){
                    sumaPoczatkowa=sumaPoczatkowa+zbior.get(i);
                   sumaKoncowa=sumaKoncowa+(zbior.get(zbior.size() - (1+i)) );
                    if ( (sum-sumaKoncowa)%3==0||(sum-sumaPoczatkowa) % 3==0) {
                        System.out.println(zbior.size() - (1+i));
                        break;
                    }}
            }


            sc.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }


}

odp

1Dl bloku: 998

2Dl bloku: 15999

3Dl bloku: 499999

0
package test;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;

public class Main5 {

	public static void main(String[] args) throws IOException {	
		
		for(int i=1; i<=3; i++) {
			System.out.println(getLongestChain(getArray(i)));
		}
	}

	public static int getLongestChain(int[] array) {
		
	    int rest[] = new int[array.length+1];
	    int firstZero = 0, lastZero = 0;
	    int lastOne = 0, firstOne = 0;
	    int lastTwo = 0, firstTwo = 0;
	   
	    for(int i=1; i<=array.length; i++) {
	        rest[i] = (rest[i-1] + array[i-1])%3;
	        
	        switch(rest[i]) {	
	        case 0: 
	        	lastZero = i;
	        	break;
	        	
	        case 1: 
	        	if(firstOne>0) lastOne = i;
	        	else firstOne = i;
	        	break;
	        
	        case 2: 
	        	if(firstTwo>0) lastTwo = i;
	        	else firstTwo = i;
	        	break;
	        }
	    }
	    int[] longest = new int[] {lastZero-firstZero, lastOne-firstOne, lastTwo-firstTwo};

	    return Arrays.stream(longest).max().getAsInt();
	}

	public static int[] getArray(int blockNumber) throws IOException {
		Scanner reader = new Scanner(new File("src\\test\\bloki"+blockNumber+".txt"));
		ArrayList<Integer> list = new ArrayList<>();
		while(reader.hasNext()) {
			list.add(reader.nextInt());
		}
		reader.close();
		return list.stream().mapToInt(i->i).toArray();	
	}
}
0

Wstawiam jeszcze proponowane rozwiązanie z informatora przepisane na jave (sam algorytm) :

	public static int getLongestChain(int[] array) {
		
		int[] beginings = new int[] {0,-1,-1};
		int restSum = 0;
		int processed = 0;
		int longest = 0;
		
		for(int i=0; i<array.length; i++) {
			
			processed++;
			restSum = (restSum + array[i]) % 3;
			
			if(beginings[restSum] == -1) {
				beginings[restSum] = processed;
			} else {
				longest = longest>processed-beginings[restSum]?longest:processed-beginings[restSum];
			}	
		}
		return longest;
	}

1 użytkowników online, w tym zalogowanych: 0, gości: 1