Submission #116801

#TimeUsernameProblemLanguageResultExecution timeMemory
116801dragonslayeritParrots (IOI11_parrots)C++14
100 / 100
1558 ms21768 KiB
#include "encoder.h" #include "encoderlib.h" #include <vector> #include <cassert> #include <string> namespace{ struct BigNum{ //LSB first std::vector<short> digits; BigNum(){ } BigNum(int num):digits({num}){ normalize(); } BigNum(std::string num){ for(int i=0;i<num.size();i++){ *this+=*this+*this+*this+*this; *this+=*this; *this+=BigNum(num[i]-'0'); } } BigNum(const char* num){ for(int i=0;num[i];i++){ *this+=*this+*this+*this+*this; *this+=*this; *this+=BigNum(num[i]-'0'); } } BigNum& normalize(){ int carry=0; for(int i=0;i<digits.size();i++){ digits[i]+=carry; int mod=digits[i]&255; int div=(digits[i]-mod)>>8; carry=div; digits[i]=mod; } assert(carry>=0); assert(carry<256); if(carry){ digits.push_back(carry); } while(digits.size()&&digits.back()==0) digits.pop_back(); return *this; } BigNum& operator+=(BigNum num){ if(digits.size()<num.digits.size()) std::swap(digits,num.digits); for(int i=0;i<num.digits.size();i++){ digits[i]+=num.digits[i]; } return normalize(); } BigNum& operator-=(BigNum num){ assert(digits.size()>=num.digits.size()); for(int i=0;i<num.digits.size();i++){ digits[i]-=num.digits[i]; } return normalize(); } BigNum operator+(BigNum num)const{ return num+=*this; } bool operator<(BigNum num)const{ if(digits.size()!=num.digits.size()) return digits.size()<num.digits.size(); for(int i=(int)digits.size()-1;i>=0;i--){ if(digits[i]!=num.digits[i]){ return digits[i]<num.digits[i]; } } return false; } bool operator==(BigNum num)const{ return !(*this<num)&&!(num<*this); } bool operator!=(BigNum num)const{ return !(*this==num); } void hexdump(){ for(int i=(int)digits.size()-1;i>=0;i--){ fprintf(stderr,"%02x",digits[i]); } } }; struct BigNum pascal[400][400]; const int P=5; } void encode(int N, int M[]) { for(int i=0;i<=N*P;i++){ pascal[i][0]=BigNum(1); } for(int j=0;j<=255;j++){ pascal[0][j]=BigNum(1); } for(int i=1;i<=N*P;i++){ for(int j=1;j<=255;j++){ pascal[i][j]=pascal[i-1][j]+pascal[i][j-1]; } } struct BigNum num; for(int i=0;i<N;i++){ num.digits.push_back(M[i]); } num.normalize(); //num.hexdump(),fprintf(stderr,"\n"); int zeros=N*P,ones=255; assert(num<pascal[zeros][ones]); std::vector<int> bits; while(zeros+ones>0){ //fprintf(stderr,"zeros=%d,ones=%d\n",zeros,ones); if(zeros>0&&num<pascal[zeros-1][ones]){ //num.hexdump(),fprintf(stderr," < "),pascal[zeros-1][ones].hexdump(),fprintf(stderr,"\n"); bits.push_back(0); zeros--; }else{ if(zeros>0){ //num.hexdump(),fprintf(stderr," >= "),pascal[zeros-1][ones].hexdump(),fprintf(stderr,"\n"); //fprintf(stderr,"Add "),pascal[zeros-1][ones].hexdump(),fprintf(stderr,"\n"); num-=pascal[zeros-1][ones]; } bits.push_back(1); ones--; } } assert(zeros==0); assert(ones==0); /* fprintf(stderr,"E:"); for(int x:bits){ fprintf(stderr,"%d",x); } fprintf(stderr,"\n"); */ int curr=0; for(int x:bits){ if(x){ curr++; }else{ send(curr); } } assert(curr==255); }
#include "decoder.h" #include "decoderlib.h" #include <vector> #include <cassert> #include <string> namespace{ struct BigNum{ //LSB first std::vector<short> digits; BigNum(){ } BigNum(int num):digits({num}){ normalize(); } BigNum(std::string num){ for(int i=0;i<num.size();i++){ *this+=*this+*this+*this+*this; *this+=*this; *this+=BigNum(num[i]-'0'); } } BigNum(const char* num){ for(int i=0;num[i];i++){ *this+=*this+*this+*this+*this; *this+=*this; *this+=BigNum(num[i]-'0'); } } BigNum& normalize(){ int carry=0; for(int i=0;i<digits.size();i++){ digits[i]+=carry; int mod=digits[i]&255; int div=(digits[i]-mod)>>8; carry=div; digits[i]=mod; } assert(carry>=0); assert(carry<256); if(carry){ digits.push_back(carry); } while(digits.size()&&digits.back()==0) digits.pop_back(); return *this; } BigNum& operator+=(BigNum num){ if(digits.size()<num.digits.size()) std::swap(digits,num.digits); for(int i=0;i<num.digits.size();i++){ digits[i]+=num.digits[i]; } return normalize(); } BigNum& operator-=(BigNum num){ assert(digits.size()>=num.digits.size()); for(int i=0;i<num.digits.size();i++){ digits[i]-=num.digits[i]; } return normalize(); } BigNum operator+(BigNum num)const{ return num+=*this; } bool operator<(BigNum num)const{ if(digits.size()!=num.digits.size()) return digits.size()<num.digits.size(); for(int i=(int)digits.size()-1;i>=0;i--){ if(digits[i]!=num.digits[i]){ return digits[i]<num.digits[i]; } } return false; } bool operator==(BigNum num)const{ return !(*this<num)&&!(num<*this); } bool operator!=(BigNum num)const{ return !(*this==num); } void hexdump(){ for(int i=(int)digits.size()-1;i>=0;i--){ fprintf(stderr,"%02x",digits[i]); } } }; struct BigNum pascal[400][400]; const int P=5; } void decode(int N, int L, int X[]) { for(int i=0;i<=N*P;i++){ pascal[i][0]=BigNum(1); } for(int j=0;j<=255;j++){ pascal[0][j]=BigNum(1); } for(int i=1;i<=N*P;i++){ for(int j=1;j<=255;j++){ pascal[i][j]=pascal[i-1][j]+pascal[i][j-1]; } } std::vector<int> cnt(256); for(int i=0;i<L;i++){ cnt[X[i]]++; } std::vector<int> bits; for(int i=0;i<256;i++){ while(cnt[i]--){ bits.push_back(0); } bits.push_back(1); } bits.pop_back(); /* fprintf(stderr,"D:"); for(int x:bits){ fprintf(stderr,"%d",x); } fprintf(stderr,"\n"); */ struct BigNum num; int zeros=0,ones=0; for(int i=(int)bits.size()-1;i>=0;i--){ if(bits[i]){ ones++; if(zeros>0){ //fprintf(stderr,"Add "),pascal[zeros-1][ones].hexdump(),fprintf(stderr,"\n"); num+=pascal[zeros-1][ones]; } }else{ zeros++; } } //num.hexdump(),fprintf(stderr,"\n"); num.digits.resize(N); for(int i=0;i<N;i++){ output(num.digits[i]); } }

Compilation message (stderr)

encoder.cpp: In constructor '{anonymous}::BigNum::BigNum(int)':
encoder.cpp:13:33: warning: narrowing conversion of 'num' from 'int' to 'short int' inside { } [-Wnarrowing]
     BigNum(int num):digits({num}){
                                 ^
encoder.cpp:13:33: warning: narrowing conversion of 'num' from 'int' to 'short int' inside { } [-Wnarrowing]
encoder.cpp: In constructor '{anonymous}::BigNum::BigNum(std::__cxx11::string)':
encoder.cpp:17:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       for(int i=0;i<num.size();i++){
                   ~^~~~~~~~~~~
encoder.cpp: In member function '{anonymous}::BigNum& {anonymous}::BigNum::normalize()':
encoder.cpp:32:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       for(int i=0;i<digits.size();i++){
                   ~^~~~~~~~~~~~~~
encoder.cpp: In member function '{anonymous}::BigNum& {anonymous}::BigNum::operator+=({anonymous}::BigNum)':
encoder.cpp:49:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       for(int i=0;i<num.digits.size();i++){
                   ~^~~~~~~~~~~~~~~~~~
encoder.cpp: In member function '{anonymous}::BigNum& {anonymous}::BigNum::operator-=({anonymous}::BigNum)':
encoder.cpp:56:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       for(int i=0;i<num.digits.size();i++){
                   ~^~~~~~~~~~~~~~~~~~

decoder.cpp: In constructor '{anonymous}::BigNum::BigNum(int)':
decoder.cpp:13:33: warning: narrowing conversion of 'num' from 'int' to 'short int' inside { } [-Wnarrowing]
     BigNum(int num):digits({num}){
                                 ^
decoder.cpp:13:33: warning: narrowing conversion of 'num' from 'int' to 'short int' inside { } [-Wnarrowing]
decoder.cpp: In constructor '{anonymous}::BigNum::BigNum(std::__cxx11::string)':
decoder.cpp:17:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       for(int i=0;i<num.size();i++){
                   ~^~~~~~~~~~~
decoder.cpp: In member function '{anonymous}::BigNum& {anonymous}::BigNum::normalize()':
decoder.cpp:32:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       for(int i=0;i<digits.size();i++){
                   ~^~~~~~~~~~~~~~
decoder.cpp: In member function '{anonymous}::BigNum& {anonymous}::BigNum::operator+=({anonymous}::BigNum)':
decoder.cpp:49:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       for(int i=0;i<num.digits.size();i++){
                   ~^~~~~~~~~~~~~~~~~~
decoder.cpp: In member function '{anonymous}::BigNum& {anonymous}::BigNum::operator-=({anonymous}::BigNum)':
decoder.cpp:56:20: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
       for(int i=0;i<num.digits.size();i++){
                   ~^~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...