błędna odp. / SPOJ

0
#include<iostream>
#include<sstream>
#include<string>
using namespace std;

int main(){
  ios_base::sync_with_stdio(0);
  short i=0, j, k;
  string d[3], *w = d;
  string::iterator it;
  stringstream ss, ss2, ss3, ss4, ss5;
  while(cin>>*w>>*w>>*(w+1)>>*(w+1)>>*(w+2)>>*(w+2)>>*(w+2)){
   while(i<3){
    if(i<2){
      it = (*w).begin();
      if('A'>*it || *it>'Z'){
         cout<<i<<endl; break;
      }
      if('A'<=*it<='Z')
         for(it++; it != (*w).end(); it++)
                   if('a'>*it || *it>'z')
                          if(*it != ';'){
                              cout<<i<<endl;
                              i=3; break;
                          }
    }
    if(i==2){
          string mm(*w, 5, 2), dz(*w, 8, 2);
          stringstream ss, ss_, ss__;
          ss<<*w; ss>>j;
          if(1900>j || j>2000){ cout<<i<<endl; break; }
          ss_<<mm; ss_>>j;
          if(1>j || j>12){ cout<<i<<endl; break; }
          ss__<<dz; ss__>>j;
          if(1>j || j>31){ cout<<i<<endl; break; }
          cout<<3<<endl;
     }
      *w++; i++;
   }
   w=d; i = 0;                   
  }  
  return 0;                  
}

Wie ktoś może dlaczego spoj wywala błędną odp. dla zadania link
Myśle, że błąd pojawia się przy sprawdzaniu daty, chociaż ja uważam że wszystko jest okey, ale coś nie gra...

0

IMHO, tutaj może być błąd:

if('A'<=*it<='Z')

Jeżeli to jest ok, to proszę mnie nie bić! ;)

0
Patryk27 napisał(a)

IMHO, tutaj może być błąd:

if('A'<=*it<='Z')

To jest akurat dobrze. Pozwoliłem się trochę pomęczyć i rozłożyłem date co odziwo zostało zaakceptowane :)

#include<iostream>
#include<sstream>
#include<string>
using namespace std;

int main(){
  ios_base::sync_with_stdio(0);
  short i=0, j, k;
  string d[3], *w = d;
  string::iterator it;
  stringstream ss, ss2, ss3, ss4, ss5;
  while(cin>>*w>>*w>>*(w+1)>>*(w+1)>>*(w+2)>>*(w+2)>>*(w+2)){
   while(i<3){
    if(i<2){
      it = (*w).begin();
      if('A'>*it || *it>'Z'){
         cout<<i<<endl; break;
      }
      if('A'<=*it<='Z'){
         for(it++; it != (*w).end(); it++){
                   if('a'>*it || *it>'z') {
                          if(*it != ';'){
                              cout<<i<<endl;
                              i=3; break;
                          }
                   }
         }
      }
    }
    if(i==2){
          stringstream ss, ss2, ss3, ss4, ss5;
          it = (*w).begin();
          ss<<*w; ss>>j;
          if(1900>j || j>2000){ cout<<i<<endl; break; }
          ss2<<*(it+5); ss2>>j;
          if(0>j || j>1) { cout<<i<<endl; break; }
          ss3<<*(it+6); ss3>>k;
          if(j==0)
           if(0>=k || k>9) { cout<<i<<endl; break; }
          if(j==1)
           if(0>k || k>2) { cout<<i<<endl; break; }
          ss4<<*(it+8); ss4>>j;
          if(0>j || j>3) { cout<<i<<endl; break; }
          ss5<<*(it+9); ss5>>k;
          if(j==0)
           if(0>=k || k>9) { cout<<i<<endl; break; }
          if(j==1)
           if(0>k || k>9) { cout<<i<<endl; break; }
          if(j==2)
           if(0>k || k>9) { cout<<i<<endl; break; }
          if(j==3)
           if(0>k || k>1) { cout<<i<<endl; break; }
          cout<<3<<endl;
     }
      *w++; i++;
   }
   w=d; i = 0;                   
  }  
  return 0;                  
}

Problem na 99% leży w dacie. Ale nie wiem dlaczego spoj nie chcę zaakceptować krótszej wersji?

0

@Shalom, dlaczego tak uważasz? skoro spoj akceptuje to musi być okey

0

Kod:

'A'<=*it<='Z'

Jest równoważny temu:

('A'<=*it)<='Z'

Język C/ C++ akceptuje różne dziwne rzeczy w ifie, pozwala porównywać wartości dowolnych typów np: if('a' < false), if(5 + true), if(a = false) itp itd To, że się coś w C/ C++ kompiluje nie oznacza, że działa tak jak wygląda :P

Przeanalizujmy sobie ten kawałek kodu:

if(i<2){
      it = (*w).begin();
      if('A'>*it || *it>'Z'){
         cout<<i<<endl; break;
      }
      if('A'<=*it<='Z'){
         for(it++; it != (*w).end(); it++){
                   if('a'>*it || *it>'z') {
                          if(*it != ';'){
                              cout<<i<<endl;
                              i=3; break;
                          }
                   }
         }
      }
    }

Jest tam coś takiego:

if('A'>*it || *it>'Z'){
         cout<<i<<endl; break;
      }

Oznacza to, iż gdy *it nie jest dużą literą to następuje break; a więc następujący po tym kod nie będzie wykonywany.

Następujący po tym kod jest taki:

if('A'<=*it<='Z'){
         for(it++; it != (*w).end(); it++){
                   if('a'>*it || *it>'z') {
                          if(*it != ';'){
                              cout<<i<<endl;
                              i=3; break;
                          }
                   }
         }
      }

Warunek:

'A'<=*it<='Z'

Dla zawsze true, ponieważ jest równoważny ('A'<=*it)<='Z', czyli zależnie od wartości *it dostaniemy true<='Z', albo false<='Z'. 'Z' jest większe zarówno od true (1) jak i false (0), tak więc warunek jako całość będzie zawsze równy true.

Mimo tego warunek wydaje się spełniać swoją rolę, ale to tylko dzięki temu, że wygląda jak przeciwieństwo warunku z poprzedniego ifa, a jeżeli warunek z poprzedniego ifa jest spełniony, to następny if nie będzie nawet wykonywany (tzn nawet sam warunek nie będzie sprawdzany).

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