troszke chyba za duzo kombinowania z tymi liczbami pierwszymi, bo to jednak zwiekszy bardziej zlozonosc programu niz bez tych liczb… narazie sprobuje to rozpykać bez liczb pierwszych po prostu uzywajac kolejnych wielkokrotnosci liczby d
wielkie dzieki
Złączono Posta : 18.10.2007 (Czw) 17:57
znlazlem, wydaje mi sie, najoptymalniejszy algorytm:
a) korzystam w nim tak jak we wczesniejszych postach pisano z wielokrotnosci liczby d
b) ‘dzielę’ tablice utworzana z zakresow a oraz b na ‘kwadratowa’ tablice i pozostalosc = po prostu poczatkowo korzystam tylko z liczb spelniajacych nizszy zakres;
-teraz aby to mialo jakis sens to wyszukuje tak liczby aby kolejnosc (y,x) nie pojawila sie, tylko korzystam wylacznie z (x,y) - przynajmniej poczatkowo; tylok ze takie uproszczenie pomija kombinacje (y,x) wiec wynik dla tej kwadratowej tabeli musi wygladac tak: wynik1=wynik_odtrzymany_kwadracie * 2 - 1
-w pozostalej czesci tablicy postepuje juz normalnie czyli sprawdzam po kolei wszystie mozliwe kombinacje (dalej korzystam z wieloktronosc d, jednak juz nie bawie się w dzielenie ‘tablicy’)
c) teraz pozostaje juz tylko dodanie obydwu wynikow i mamy calkowita liczbe mozliwych kombinacji
tutaj moj kod w javie:
//Rafał C***t 2007
import java.io.*;
import java.util.*;
public class zapytania{
static int nwd(int x, int y){
int c;
while (y != 0) {
c = x % y;
x = y;
y = c;}
return x;
}
static int min(int poczatek, int skok){
while(poczatek%skok!=0)
poczatek++;
return poczatek;
}
public static void main(String[] args){
BufferedReader wejscie = new BufferedReader( new InputStreamReader(System.in) );
int n; //liczba zapytan
int a, b, d, wynik, wynik_temp, min;
int[] wynik_koncowy;
try{
n = Integer.parseInt( wejscie.readLine() );
StringTokenizer st;
wynik_koncowy = new int[n];
for(int i=0; i
st = new StringTokenizer(wejscie.readLine(), " ");
a = Integer.parseInt( st.nextToken() );
b = Integer.parseInt( st.nextToken() );
d = Integer.parseInt( st.nextToken() );
wynik=0;wynik_temp=0;
if(a>b){
for(int x=d; x<=b; x+=d) //zacznij od nwd i zwiekszaj je o nwd, nie sprawdza do konca aby oszczedzic
for(int y=x; y<=b; y+=d) //y=x skrocenie tyczas. o polowe szukanie par
if(nwd(x,y)==d) wynik++; //jesli nwd(x,y) jest rowne d to zwieksz liczbe par
if(wynik>0) wynik_temp=2*wynik - 1; //prawidlowy wynik dla przedzialu (wynika ze skrocenia: patrz 2 linijki wyzej)
min = min(b+1,d); //znalezienie nowej dolnej granicy przedzialu pominietego wyzej
wynik=0; //inicjacja na nowo zmiennej wynik
for(int x=min; x<=a; x+=d) //rozpoczecie szukania od nowgo przedzialu
for(int y=d; y<=b; y+=d) //a tutaj szukanie za porzadkiem
if(nwd(x,y)==d) wynik++;
wynik_koncowy[i]=wynik+wynik_temp; //suma z obydwu przedzialow
}
else if(a
for(int x=d; x<=a; x+=d)
for(int y=x; y<=a; y+=d)
if(nwd(x,y)==d) wynik++;
if(wynik>0) wynik_temp=2*wynik - 1;
min = min(a+1,d);
wynik=0;
for(int x=d; x<=a; x+=d)
for(int y=min; y<=b; y+=d)
if(nwd(x,y)==d) wynik++;
wynik_koncowy[i]=wynik+wynik_temp;
}
else{ // a==b
for(int x=d; x<=a; x+=d)
for(int y=x; y<=a; y+=d)
if(nwd(x,y)==d) wynik++;
if(wynik>0) wynik_temp=2*wynik - 1;
wynik_koncowy[i]=wynik_temp;
}
}
for(int i=0;i
System.out.println(wynik_koncowy[i]);
}
catch(IOException w){};
}
}
//Rafał C***t 2007[/code]