Informatică, întrebare adresată de ionutg38, 9 ani în urmă

Dându-se o dată calendaristică și un număr nr de zile, să se determine care este data aflată la o diferență de nr de zile.

Date de intrare
Programul citește de la tastatură 3 numere naturale Z, L și A, reprezentând ziua, luna si anul curent, iar pe al doilea rând numărul nr de zile.

Date de ieșire
Programul va afișa pe ecran 3 numere naturale ZI, LUNA, AN reprezentând data cerută.

Restricții și precizări
-100.000 ≤ nr ≤ 100000
Datele calendaristice din fișierul de intrare sunt între 1 ianuarie 1900 și 31 decembrie 2100
Nu se vor fi date calendaristice invalide precum 29 februarie 2015 sau 31 noiembrie 1980
Dacă nr este negativ, data cerută se afla înaintea cele curente.
Exemple:
Intrare

6 1 2015
15
Ieșire

21 1 2015
Intrare

6 1 2015
-7
Ieșire

30 12 2014


blindseeker90: Asta e o rezolvare aproximativa pentru ca nu am testat prea mult

Răspunsuri la întrebare

Răspuns de blindseeker90
4
#include <iostream>
using namespace std;

long int transforma_data_zile(int Z,int L,int A){

long int zile_curente=Z,ani_bisecti,bisect=0;
L--;
while(L>0){
if(L<8){
if(L%2==1){
zile_curente=zile_curente+31;
}
else{
if(L==2){
zile_curente=zile_curente+28;
}
else{
zile_curente=zile_curente+30;
}
}
}
else{
if(L%2==1){
zile_curente=zile_curente+30;
}
else{
zile_curente=zile_curente+31;
}
}

L--;
}
//pentru a adauga ziua de 29 feb pentru ani bisecti
if(A%4==0&&zile_curente>59){
zile_curente++;
bisect=1;
}
//adaugam 1 pentru anul bisect 1900
if(bisect==1){
ani_bisecti=A/4;
}
else{
ani_bisecti=A/4+1;
}

zile_curente=zile_curente+A*365+ani_bisecti;

return zile_curente;
}
void transforma_zile_data(long int zile_curente){
int Z,L,A,bisect=0,ani_bisecti;
A=zile_curente/365;
zile_curente=zile_curente%365;
if(A%4==0){
ani_bisecti=A/4;
bisect=1;
}
else{
ani_bisecti=A/4+1;
bisect=0;
}
zile_curente=zile_curente-ani_bisecti;

L=zile_curente/30+1;
Z=zile_curente%30;
if(L>=3&&Z>=0){

if(bisect==0){
Z=Z+2;
}
else{
Z=Z+1;
}

}
if(L<=8){
Z=Z-L/2;
}
else{
Z=Z-(L/2+1);
}
if(Z>30){

if(L<8){
if(L%2==1){
Z=Z-31;
}
else{
Z=Z-30;
}
}
else{
if(L%2==1){
Z=Z-30;
}
else{
Z=Z-31;
}
}

}
else if(Z<=0){
if(L>1){
L--;
if(L<8){
if(L%2==1){
Z=Z+31;
}
else{
Z=Z+30;
}
}
else{
if(L%2==1){
Z=Z+30;
}
else{
Z=Z+31;
}
}
}
else{
A--;
L=12;
Z=31+Z;
}

}
cout<<Z<<" "<<L<<" "<<A+1900;

}
int main(){

long int Z,L,A,nr,ani_dif,zile_curente,zile_dif,zile_bis=0,feb_bisect,zile_an=365;
cin>>Z>>L>>A;
cin>>nr;
A=A-1900;
zile_curente=transforma_data_zile(Z,L,A);
zile_curente=zile_curente+nr;
transforma_zile_data(zile_curente);

return 0;
}

ionutg38: A trecut cateva teste (26 puncte din 100). Multumesc!
ionutg38: Erau si cateva indicatii:
ionutg38: Vom folosi 4 variabile nr, z, l, a și un vector luni_calendaristice[12] care va conține numărul de zile din fiecare lună.

Problema se poate rezolva în mai multe moduri:

1) Secvențial: efectuăm nr pași și modificăm la fiecare pas variabila z. Dacă z depășește intervalul de zile din luna respectivă, modificăm l, dacă l ia valoarea 0 sau 13 îl modificăm pe a.
ionutg38: 2) Secvențial pe luni: Verificăm dacă putem adăuga/scădea numărul de zile pentru luna curentă și repetăm procesul cât timp |nr| > 0. (nr ia valoarea |nr| înainte de a efectua scăderile) Scădem din |nr| numărul de zile din luna respectivă, apoi efectuăm procesul similar pentru fiecare zi cât timp |nr| > 0.
ionutg38: 3) Secvențial pe ani: Efectuăm scăderile similar pe ani, apoi repetăm procesul pentru fiecare lună și apoi pentru zile.

Mare grijă la anii bisecți! Un an poate fi bisect dacă este divizibil cu 4. Nu este bisect dacă este divizibil cu 100 și nu este divizibil cu 400.
Alte întrebări interesante