CodeChef submission 131081 (C++ 4.0.0-8) plaintext list. Status: AC, problem JX, contest NOV09. By anshuman_singh (Anshuman Singh), 2009-11-11 14:55:11.
#include<iostream> #include<cstdio> #include<cstring> #include<cstdlib> #include<map> #include<vector> #include<list> #include<set> #include<queue> #include<cassert> #include<sstream> #include<string> #include<cmath> #include<algorithm> #include<climits> using namespace std; #define LET(x,a) __typeof(a) x(a) #define IFOR(i,a,b) for(LET(i,a);i!=(b);++i) #define EACH(it,v) IFOR(it,v.begin(),v.end()) #define FOR(i,a,b) for(int i=(int)(a) ; i < (int)(b);++i) #define REP(i,n) FOR(i,0,n) #define PB push_back #define MP make_pair #define EPS 1e-9 #define INF 2000000000 typedef vector<int> VI; typedef long long LL; typedef pair<int,int> PI; #define BUFSIZE (1000000) char outputbuffer[BUFSIZE<<1],inputbuffer[BUFSIZE]; char *outptr=outputbuffer,*ioptr=inputbuffer+BUFSIZE,*ioend=inputbuffer+BUFSIZE; int input_eof=0; #define putchar(c) (*outptr++ = (c)) #define getchar() ({if (ioptr >= ioend) init_input(); *ioptr++;}) #define eof() (ioptr>=ioend && input_eof) #define eoln() ({if(ioptr >= ioend) init_input(); *ioptr == '\n';}) void init_input(){ if (input_eof) return; int existing = BUFSIZE - (ioend - inputbuffer); int wanted = ioend - inputbuffer; if (count < wanted) input_eof = 1; ioend = inputbuffer + BUFSIZE - (wanted - count); while (*--ioend > ' '); ioend++; ioptr=inputbuffer; } inline void non_whitespace(){ for(;;){ if(ioptr>=ioend) init_input(); if(*ioptr>' ') return; ioptr++; } } void flush_output(){ outptr=outputbuffer; } inline void check_output(){ if(outptr>=outputbuffer+BUFSIZE) flush_output(); } inline int getint(){ non_whitespace(); int neg=0; if(*ioptr=='-'){ ioptr++; neg=1; } int n=0; while(*ioptr>' ') n=(n<<3)+(n<<1)+*ioptr++-'0'; ioptr++; if(neg) n=-n; return n; } inline void putint(int n){ char buffer[10]; int i=0,n2; do{ n2=n/10; buffer[i++]=n-(n2<<3)-(n2<<1)+'0'; }while((n=n2)); while(i) check_output(); } inline void putstr(char *str){ int i=0; check_output(); return; } int d,s; int b[1000],like[1000],dislike[1000],present[1000],ind; int M[501][501];//[song][dancers] bool taken[501],tempTaken[501],tempTaken2[501],tempTaken3[501]; int globalScore=0; int findScore(){ int score=0; REP(i,d)if(like[i] && dislike[i]<b[i])score++; return score; } void Update(){ int Score=findScore(); if(Score>globalScore){ globalScore=Score; REP(i,s)taken[i]=tempTaken[i]; } return; } void discard(int i){ REP(j,d){ if(M[i][j])like[j]--; else dislike[j]--; } tempTaken[i]=0; return; } void doIter(){ while(1){ int maxscore=0; int maxIndex=-1; REP(i,s){ if(tempTaken[i])continue; int score=0,score2=0; REP(j,d){ if(dislike[j]>=b[j])continue; if(!like[j] && M[i][j]){ score+=10000;score2++;continue; } if(!M[i][j] && dislike[j]==b[j]-1 && like[j]){ score2--;score-=10000;continue; } if(M[i][j]){ score+=(10000/(b[j]-dislike[j]));continue; } } if(score2>0 && score>maxscore){ maxscore=score; maxIndex=i; } } if(maxscore<10)break; tempTaken[maxIndex]=1; REP(i,d){ if(M[maxIndex][i])like[i]++; else dislike[i]++; } } return; } void doIter2(){ int maxscore2=-1; while(1){ int maxscore=0,maxIndex=-1; REP(i,s)if(tempTaken[i] && !tempTaken3[i]){ int score=0; REP(j,d){ if(M[i][j] && like[j]==1 && dislike[j]<b[j])score++; if(!M[i][j] && like[j] && dislike[j]==b[j])score--; } if(score>maxscore){ maxscore=score; maxIndex=i; } } if(maxscore < maxscore2 && maxIndex!=-1){ discard(maxIndex); continue; } maxscore=0;maxIndex=-1;maxscore2=0; REP(i,s){ if(tempTaken[i]||tempTaken3[i])continue; int score=0,score2=0; REP(j,d){ if(dislike[j]>=b[j])continue; if(!like[j] && M[i][j]){ score+=10000;score2++;continue; } if(!M[i][j] && dislike[j]==b[j]-1 && like[j]){ score2--;score-=10000;continue; } if(M[i][j]){ score+=(10000/(b[j]-dislike[j]));continue; } } if(score2>0 && score2>maxscore2){ maxscore=score; maxscore2=score2; maxIndex=i; } else if(score2>0 && ((score2==maxscore2||score2==maxscore2-1) && score>maxscore)){ maxscore=score; maxscore2=score2; maxIndex=i; } } if(maxscore2<1)break; tempTaken[maxIndex]=1; REP(i,d){ if(M[maxIndex][i])like[i]++; else dislike[i]++; } } return; } int findScore2(int ind){ int ret=0; REP(i,d){ if(M[ind][i])ret+=100000; else { if(b[i])ret-=100000/b[i]; } } return ret; } void process2(){ if(s<30||d<30)return; for(int x=11;x<=200;x+=20){ if(x>=s)continue; // REP(i,10){ // int x=rand()%s; // if(visited[x])while(visited[x])x=rand()%s; // visited[x]=1; tempTaken3[x]=1; REP(i,s)tempTaken[i]=0; REP(i,d)like[i]=dislike[i]=0; doIter2(); Update(); tempTaken3[x]=0; } return; } void process3(){ FOR(i,160,500)visited[i]=1; if(s<30||d<30)return; int toTry[]={19,25,36,44,49,81,97,100,121,144}; int lim = min(s,160); REP(ii,15){ // int x=order[ii].second; //REP(i,15){ if(ii>=5 && !visited[toTry[ii-5]])x=toTry[ii-5]; visited[x]=1; if(x>=s)continue; tempTaken2[x]=1; REP(i,s)tempTaken[i]=0; REP(i,d)like[i]=dislike[i]=0; tempTaken[x]=1; REP(i,d){ if(M[x][i])like[i]++; else dislike[i]++; } doIter2(); Update(); tempTaken2[x]=0; } return; } void process12(){ int lim = min(22,s/2); REP(i,lim){ visited[x]=1; tempTaken3[x]=1; REP(i,s)tempTaken[i]=0; REP(i,d)like[i]=dislike[i]=0; doIter2(); Update(); tempTaken3[x]=0; } return; } void process13(){ int lim = min(22,s/2); REP(i,lim){ visited[x]=1; tempTaken2[x]=1; REP(i,s)tempTaken[i]=0; REP(i,d)like[i]=dislike[i]=0; tempTaken[x]=1; REP(i,d){ if(M[x][i])like[i]++; else dislike[i]++; } doIter2(); Update(); tempTaken2[x]=0; } return; } void reset(){ REP(i,s)tempTaken[i]=taken[i]; REP(j,d)like[j]=dislike[j]=0; REP(i,s)if(tempTaken[i])REP(j,d){ if(M[i][j])like[j]++; else dislike[j]++; } return; } PI order[501]; bool changed; int main(){ init_input(); d=getint(); s=getint(); REP(i,d){ b[i]=getint(); b[i]=min(s+1,b[i]); } REP(i,d)REP(j,s)M[j][i]=getint(); globalScore=0; /***************** Method 1 **************************************/ doIter(); Update(); /***********************************Method 1 ends here **********************************/ if(d>70){ process2(); process3(); } else { process12(); // process13(); } /****************** Trying to improve initial approach**********************************/ if(s<=60 && d<=60){ REP(i,s)tempTaken[i]=0; REP(i,d)like[i]=dislike[i]=0; int mscore=0,mscore2=0; int p1,p2,p3; REP(i,s)FOR(j,i+1,s)FOR(k,j+1,s){ int score=0,score2=0; REP(l,d){ int lik=0,dis=0; if(M[i][l])lik++;else dis++; if(M[j][l])lik++;else dis++; if(M[k][l])lik++;else dis++; if(lik)score2+=10000; if(dis>=b[l])score2-=10000; else score+=(10000/(b[l]-dis)); } if(score2>mscore2 || (score2==mscore2 && score>mscore)){ mscore=score; mscore2=score2; p1=i;p2=j;p3=k; } } if(mscore2<=0){ reset(); } else { tempTaken[p1]=1; tempTaken[p2]=1; tempTaken[p3]=1; REP(i,d){ if(M[p1][i])like[i]++;else dislike[i]++; if(M[p2][i])like[i]++;else dislike[i]++; if(M[p3][i])like[i]++;else dislike[i]++; } doIter(); Update(); } } if(s<=400) { REP(i,s)tempTaken[i]=0; REP(i,d)like[i]=dislike[i]=0; int mscore=0,mscore2=0; int p1,p2; REP(i,s)FOR(j,i+1,s){ int score=0,score2=0; REP(l,d){ int lik=0,dis=0; if(M[i][l])lik++;else dis++; if(M[j][l])lik++;else dis++; if(lik)score2+=10000; if(dis>=b[l])score2-=10000; else score+=(10000/(b[l]-dis)); } if(score2>mscore2 || (score2==mscore2 && score>mscore)){ mscore=score; mscore2=score2; p1=i;p2=j; } } if(mscore2<=0){ reset(); } else { tempTaken[p1]=1; tempTaken[p2]=1; REP(i,d){ if(M[p1][i])like[i]++;else dislike[i]++; if(M[p2][i])like[i]++;else dislike[i]++; } doIter(); Update(); } } reset(); /********************************** Trying Method 2 here ********************************/ changed=true; while(changed){ changed=false; REP(i,s)tempTaken2[i]=tempTaken[i]; REP(i,s)if(tempTaken[i]){ discard(i); doIter(); Update(); } REP(i,s)if(tempTaken2[i]!=tempTaken[i])changed=true; } /**********************************Method 2 ends here ***********************************/ int iter=0; while(iter<8){ iter++; /*********************************One more method ***************************************/ reset(); ind=0; REP(i,s)if(tempTaken[i])present[ind++]=i; REP(i,50){ if(ind<=2)break; a1 = present[a1]; a2 = present[a2]; discard(a1);discard(a2); doIter(); Update(); ind=0; REP(i,s)if(tempTaken[i])present[ind++]=i; } reset(); ind=0; REP(i,s)if(tempTaken[i])present[ind++]=i; REP(i,60){ if(ind<=3)break; a1 = present[a1]; a2 = present[a2]; a3 = present[a3]; discard(a1);discard(a2);discard(a3); doIter(); Update(); ind=0; REP(i,s)if(tempTaken[i])present[ind++]=i; } reset(); ind=0; REP(i,s)if(tempTaken[i])present[ind++]=i; int lim=10; if(d<=100)lim=15; REP(i,lim){ if(ind<=4)break; a1 = present[a1]; a2 = present[a2]; a3 = present[a3]; a4 = present[a4]; discard(a1);discard(a2);discard(a3);discard(a4); doIter(); Update(); ind=0; REP(i,s)if(tempTaken[i])present[ind++]=i; } reset(); ind=0; REP(i,s)if(tempTaken[i])present[ind++]=i; lim=4; if(d<=100)lim=8; REP(i,lim){ if(ind<=5)break; a1 = present[a1]; a2 = present[a2]; a3 = present[a3]; a4 = present[a4]; a5 = present[a5]; discard(a1);discard(a2);discard(a3);discard(a4);discard(a5); doIter(); Update(); ind=0; REP(i,s)if(tempTaken[i])present[ind++]=i; } lim=5; REP(i,lim){ if(ind<=6)break; a1 = present[a1]; a2 = present[a2]; a3 = present[a3]; a4 = present[a4]; a5 = present[a5]; a6 = present[a6]; discard(a1);discard(a2);discard(a3);discard(a4);discard(a5);discard(a6); doIter2(); Update(); ind=0; REP(i,s)if(tempTaken[i])present[ind++]=i; } lim=3; if(d<=100)lim=6; REP(i,lim){ if(ind<=5)break; random_shuffle(present,present+ind); if(tmp<=2)tmp=3; REP(j,tmp)discard(present[j]); doIter(); Update(); ind=0; REP(i,s)if(tempTaken[i])present[ind++]=i; } if(d>100)break; } /********************************** Output here *****************************************/ int cnt=0; REP(i,s)if(taken[i])cnt++; putint(cnt);putchar(10); REP(i,s)if(taken[i]){ putint(i); } flush_output(); return 0; }
Comments

