Sveikas, šis uždavinys iš tiesų yra lengvas, jo sąlygoje trūktsta tik vieno svarbaus dalyko - atskaitos taško t.y kiekvienų metų sausio 1 savaitės dienos numerio. Sprendžiant uždavinius yra geriausiai susimažinti į mažesnes problemas, t.y pvz.: ne ieškoti metų intervale, o tik tuose pačiuose metuose.
bool isLeapYear(int n){ // Ar keliamieji metai
return (n % 400 == 0) || (n % 100 != 0 && n % 4 == 0);
}
int months[13] = { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // Mėnesiai
void findIMonths(int year, int fday){ // Metai, tų metų sausio 1 dienos savaitės numeris
int leapAddup = isLeapYear(year), fridays, sundays, saturdays, m, d;
cout << year << ": ";
for(m = 1; m <= 12; m++){ // per visus menesius
fridays = 0, sundays = 0, saturdays = 0;
for(d = 1; d <= (m == 2 ? months[m] + leapAddup : months[m]); d++){ // Einam per visas dienas
if(fday == 5) fridays++;
if(fday == 6) sundays++;
if(fday == 7) saturdays++;
fday = (fday % 7) + 1; // Pereinam prie kitos savaitės dienos
}
if(fridays == 5 && sundays == 5 && saturdays == 5)
cout << m << " ";
}
cout << endl;
}
Ši funkcija suranda ir išspausdina kuriuose mėnesiuose įvyksta įdomūs mėnesiai. - Funkcija "isLeapYear" gražina ar metai keliamieji ar ne, kadangi į tai reikia irgi atsižvelgti. - Kintamasis leapAddup yra reikšmė kurią reikia pridėti vasario mėnesį jei metai yra keliamieji. - "(m == 2 ? months[m] + leapAddup : months[m])" ši eilutė tikrina jei yra vasario mėnuo tai reikia pridėti kintamajį leapAddup, kuris gražina 0 arba 1.
Vienintelis klausimas lieka, kaip reikia surasti kiekvienų metų sausio 1 dienos numerį. Tam yra reikalingas kažkoks atskaitos taškas. Logiškiausia būtu pasiimti kažkokius metus kurių sausio 1 diena būtų pirmadienis. Tam galim pasinaudot kalendorių.
http://puu.sh/nntaX/6dc58a9f4f.png
Matom kad 1990 metų sausio 1 diena yra pirmadienis, tai mes galime panaudoti. Taigi dabar tereikia sukurti naują funkciją kuri apskaičiuotu įvedus metus didesnius 1989 kokia savaitės diena yra tų metų sausio 1 diena. Kadangi mes ėmėme 1990 metus kaip atskaitos tašką, ieškant mažesniuose metuose reikšmės gaunasi neigiamos tokiu atveju reikėtu papildomų sąlygų, bet į tai nesigilinsime.
int findFirstDay(int year){
int y, m, d, resultDay = 1, leapAddup; // Reikšmės ir rezultatų diena
for(y = 1990; y < year; y++){ // Per visus metus, nuo 1990 iki (neįskaitant) ieškomų
leapAddup = isLeapYear(y);
for(m = 1; m <= 12; m++){ // Per visus mėnesius
for(d = 1; d <= (m == 2 ? months[m] + leapAddup : months[m]); d++){ // Per visas dienas nepamirštam keliamūju
resultDay = (resultDay % 7) + 1; // Pereinam prie kitos savaitės dienos
}
}
}
return resultDay;
}
Štai ir pasirašėme funkciją kuri suranda kokia yra metų (didesnių nei 1989) sausio 1 savaitės diena. Kadangi išsprendėme visas problemas, bereikia nuskaityti duomenis, prasukti vieną ciklą per visus norimus metus ir uždavinys išspręstas ;)