///sto cistije *,ponavljanja,ista slova #include using namespace std; #define ll long long #define pb push_back #define db double #define ff first #define ss second const ll maxN=10510; const ll p=31; const ll mod=1e9+9; bool nemavremena=false; clock_t begin_time=0; clock_t time_alowed_for_word=0; const double timelimit=4.2; clock_t vremePoSlovu=0; clock_t begin_time_for_word=0; struct rec { string sorce; vector hasheds; vector> start; string solution; ll index; ll nacin; ll n; ll brmax; }; ll n,t,maxi=0,maxx=5,maxy=3,zbirn=0,x=5,y=2,proseky,suman=0; char resenje[4000][maxN]; string text=""; string rek=""; vector reci; ll pow_p[maxN]; set posebni; vector> kombinacije; ll lista[10]; ll mini=INT_MAX; void kombinuj(ll now,ll n) { if(now==5){ vector ubaci; for(int i=1;i<=4;i++){ ubaci.pb(lista[i]); } kombinacije.pb(ubaci); return; } for(int i=lista[now-1]+1;i<=n;i++){ lista[now]=i; kombinuj(now+1,n); lista[now]=0; } return; } ll hashing(string const& now) { ll vrati=0; for(int i=0;i hashuj(const string &s) { vector vrati; ll suma=0; for(int i=0;iy.n; } bool cmpend(rec x,rec y) { return x.index najbolji; ll najvise=-1; ll temp=0; for(auto k:kombinacije){ temp=0; posebni.clear(); for(auto o:k) posebni.insert(o+'a'-1); resenje[1][2]='a'+k[0]-1; resenje[3][2]='a'+k[1]-1; resenje[2][1]='a'+k[2]-1; resenje[2][3]='a'+k[3]-1; for(int i=0;inajvise){ najbolji=k; najvise=temp; } } if(najvise<=0){ resenje[1][2]=0; resenje[3][2]=0; resenje[2][1]=0; resenje[2][3]=0; resenje[2][2]=0; return; } posebni.clear(); for(auto o:najbolji) posebni.insert(o+'a'-1); resenje[1][2]='a'+najbolji[0]-1; resenje[3][2]='a'+najbolji[1]-1; resenje[2][1]='a'+najbolji[2]-1; resenje[2][3]='a'+najbolji[3]-1; for(int i=0;i1){ ll t=reci[now].n-1; if(resenje[1][2]==reci[now].sorce[t])reci[now].solution+= "U"; else if(resenje[3][2]==reci[now].sorce[t])reci[now].solution+= "D"; else if(resenje[2][1]==reci[now].sorce[t])reci[now].solution+= "L"; else reci[now].solution+= "R"; } return; } ll alreadyIn(const ll now) { ll nowHash = reci[now].hasheds.back(); ll l = reci[now].n; for(int sada=0;sada0)lrHash-=reci[sada].hasheds[i-1]; lrHash+=mod; lrHash%=mod; if((nowHash*pow_p[i])%mod == lrHash){ reci[now].solution+= reci[sada].solution.substr(i,l-1); for(int j=i;j x,pair y) { if(x.ss==y.ss) return x.ff=s.size()){ if(resenje[nowy][nowx+1]==0 && resenje[nowy][nowx+2]==0)return true; return false; } if(resenje[nowy][nowx+1]==s[nowi]){ if(probabfs(s,nowx+1,nowy,nowi+1))return true; } if(resenje[nowy+1][nowx]==s[nowi]){ if(probabfs(s,nowx,nowy+1,nowi+1))return true; } if(resenje[nowy-1][nowx]==s[nowi]){ if(probabfs(s,nowx,nowy-1,nowi+1))return true; } if(resenje[nowy][nowx-1]==s[nowi]){ if(probabfs(s,nowx-1,nowy,nowi+1))return true; } return false; } deque> proba; bool bio=false; void pravibfs(string s,ll nowx,ll nowy,ll nowi,ll now) { if(bio)return; if(nowi>=s.size()){ if(resenje[nowy][nowx+1]==0 && resenje[nowy][nowx+2]==0){ if(bio)return; bio=true; x=nowx; y=nowy; reci[now].solution+=rek; for(auto i:proba) { reci[now].start.pb(i); } return; } return; } if(resenje[nowy][nowx+1]==s[nowi]){ rek+='R'; proba.pb({nowx,nowy-1}); pravibfs(s,nowx+1,nowy,nowi+1,now); proba.pop_back(); rek.pop_back(); } if(resenje[nowy+1][nowx]==s[nowi]){ rek+='D'; proba.pb({nowx-1,nowy}); pravibfs(s,nowx,nowy+1,nowi+1,now); proba.pop_back(); rek.pop_back(); } if(resenje[nowy-1][nowx]==s[nowi]){ rek+='U'; proba.pb({nowx-1,nowy-2}); pravibfs(s,nowx,nowy-1,nowi+1,now); proba.pop_back(); rek.pop_back(); } if(resenje[nowy][nowx-1]==s[nowi]){ rek+='L'; proba.pb({nowx-2,nowy-1}); pravibfs(s,nowx-1,nowy,nowi+1,now); proba.pop_back(); rek.pop_back(); } return; } void postavi(ll now) { vector> isto; isto.pb({INT_MAX,INT_MAX}); string rec=reci[now].sorce; ll nn=rec.size(); for(int i=0;i0){ if(i+1isto[temp].ff){ temp++; } if(iisto[temp].ff){ if(i)x++; resenje[y][x]=rec[i]; reci[now].start.pb({x-1,y-1}); if(i)reci[now].solution.pb('R'); i++; maxx=max(maxx,x); maxy=max(maxy,y); } else if(i==isto[temp].ff){ if(i)y++; if(i)reci[now].solution.pb('D'); maxy=max(maxy,y); resenje[y][x]=rec[i]; reci[now].start.pb({x-1,y-1}); x--; i++; resenje[y][x]=rec[i]; reci[now].start.pb({x-1,y-1}); i++; reci[now].solution.pb('L'); ll brojac=(isto[temp].ss-isto[temp].ff-2)/2; ll brojac2=brojac; maxx=max(maxx,x); maxy=max(maxy,y); while(brojac--){ y++; reci[now].solution.pb('D'); resenje[y][x]=rec[i]; reci[now].start.pb({x-1,y-1}); i++; } maxx=max(maxx,x); maxy=max(maxy,y); if(brojac2){ x++; reci[now].solution.pb('R'); resenje[y][x]=rec[i]; reci[now].start.pb({x-1,y-1}); i++; brojac2--; maxx=max(maxx,x); maxy=max(maxy,y); } while(brojac2--){ y--; reci[now].solution.pb('U'); resenje[y][x]=rec[i]; reci[now].start.pb({x-1,y-1}); i++; } maxx=max(maxx,x); maxy=max(maxy,y); if((isto[temp].ss-isto[temp].ff-2)/2>0){ y--; reci[now].solution.pb('U'); reci[now].start.pb({x-1,y-1}); i++; } else{ x++; reci[now].solution.pb('R'); reci[now].start.pb({x-1,y-1}); i++; } string pon=""; ll naj=-1; for(int ponovo=0;ponovo<40 && ponovo+i=0)pravibfs(pon.substr(0,naj+1),x,y,0,now); i+=naj+1; if(i+1150){ if(i+1 time_alowed_for_word) nemavremenazarec=true; if(nemavremenazarec) return -1; //if(nemavremena)return -1; if(nowi==reci[now].n){ br++; return skor; } //if(ajmoprobamax>skor+reci[now].n-nowi && ajmoprobamax>2)return -1; ll vrati=-1; char c = reci[now].sorce[nowi]; if(resenje[nowy][nowx+1]==c || biomat[nowy][nowx+1]==c){ vrati=max(vrati,ajmoproba(nowx+1,nowy,now,nowi+1,skor+1)); ajmoprobamax=max(ajmoprobamax,vrati); } if(br>=reci[now].brmax)return vrati; if(resenje[nowy][nowx-1]==c || biomat[nowy][nowx-1]==c){ vrati=max(vrati,ajmoproba(nowx-1,nowy,now,nowi+1,skor+1)); ajmoprobamax=max(ajmoprobamax,vrati); } if(br>=reci[now].brmax)return vrati; if(resenje[nowy+1][nowx]==c || biomat[nowy+1][nowx]==c){ vrati=max(vrati,ajmoproba(nowx,nowy+1,now,nowi+1,skor+1)); ajmoprobamax=max(ajmoprobamax,vrati); } if(br>=reci[now].brmax)return vrati; if(resenje[nowy-1][nowx]==c || biomat[nowy-1][nowx]==c){ vrati=max(vrati,ajmoproba(nowx,nowy-1,now,nowi+1,skor+1)); ajmoprobamax=max(ajmoprobamax,vrati); } if(br>=reci[now].brmax)return vrati; if(resenje[nowy+1][nowx]==0 && biomat[nowy+1][nowx]==0){ biomat[nowy+1][nowx]=c; vrati=max(vrati,ajmoproba(nowx,nowy+1,now,nowi+1,skor)); ajmoprobamax=max(ajmoprobamax,vrati); biomat[nowy+1][nowx]=0; } if(br>=reci[now].brmax)return vrati; if(resenje[nowy][nowx+1]==0 && biomat[nowy][nowx+1]==0){ biomat[nowy][nowx+1]=c; vrati=max(vrati,ajmoproba(nowx+1,nowy,now,nowi+1,skor)); ajmoprobamax=max(ajmoprobamax,vrati); biomat[nowy][nowx+1]=0; } if(br>=reci[now].brmax)return vrati; if(resenje[nowy][nowx-1]==0 && biomat[nowy][nowx-1]==0){ biomat[nowy][nowx-1]=c; vrati=max(vrati,ajmoproba(nowx-1,nowy,now,nowi+1,skor)); ajmoprobamax=max(ajmoprobamax,vrati); biomat[nowy][nowx-1]=0; } if(br>=reci[now].brmax)return vrati; if(resenje[nowy-1][nowx]==0 && biomat[nowy-1][nowx]==0){ biomat[nowy-1][nowx]=c; vrati=max(vrati,ajmoproba(nowx,nowy-1,now,nowi+1,skor)); ajmoprobamax=max(ajmoprobamax,vrati); biomat[nowy-1][nowx]=0; } return vrati; } ll naj=-1; void ajmo(ll nowx,ll nowy,ll now,ll nowi,ll score) { if(score+reci[now].n-nowitimelimit)nemavremena=true; //if(nemavremena)return; if(bio)return; if(nowi==reci[now].n){ if(score2){ y--; resenje[y][x]=reci[now].sorce[cnt]; if(cnt)reci[now].solution.pb('U'); reci[now].start.pb({x-1,y-1}); } else if(gore && y==2){ x++; resenje[y][x]=reci[now].sorce[cnt]; if(cnt)reci[now].solution.pb('R'); reci[now].start.pb({x-1,y-1}); gore=false; } else if(gore==false && y> mesta[40]; for(int i=0;i0) x++; naj=-1; pair mesto={x,y}; nemavremenazarec=false; resenje[y][x]=reci[i].sorce[0]; begin_time_for_word = clock(); time_alowed_for_word= vremePoSlovu *(double)reci[i].n; br=0; ajmoprobamax=-1; ll temp=ajmoproba(x,y,i,1,1); if(float( clock () - begin_time ) / CLOCKS_PER_SEC > timelimit) nemavremena=true; if(nemavremena){ naj=-1; break; } if(temp>naj){ naj=temp; } if(naj==-1){ resenje[y][x]=0; if(nemavremena){ resivreme(i); return; } while(resenje[y][x]>0) x++; bool nasao=false; while(!nasao){ bool moze=true; for(int j=0;j mesto={0,0}; nemavremenazarec=false; begin_time_for_word = clock(); time_alowed_for_word= vremePoSlovu *(double)reci[i].n; for(auto j: mesta[reci[i].sorce[0]-'a']){ br=0; ajmoprobamax=-1; ll temp=ajmoproba(j.ff,j.ss,i,1,1); if(float( clock () - begin_time ) / CLOCKS_PER_SEC > timelimit) nemavremena=true; if(nemavremena){ naj=-1; break; } if(temp>naj){ naj=temp; mesto=j; } if(nemavremenazarec)break; } if(naj==-1){ naj=-1; while(resenje[y][x]>0) x++; pair mesto={x,y}; nemavremenazarec=false; resenje[y][x]=reci[i].sorce[0]; begin_time_for_word = clock(); time_alowed_for_word= vremePoSlovu *(double)reci[i].n; br=0; ajmoprobamax=-1; ll temp=ajmoproba(x,y,i,1,1); if(float( clock () - begin_time ) / CLOCKS_PER_SEC > timelimit) nemavremena=true; if(nemavremena){ naj=-1; break; } if(temp>naj){ naj=temp; } if(naj==-1){ resenje[y][x]=0; if(nemavremena){ resivreme(i); return; } while(resenje[y][x]>0) x++; bool nasao=false; while(!nasao){ bool moze=true; for(int j=0;j> t >> n; for(int i=0;i> now; rec temp; temp.n=now.size(); temp.sorce=now; temp.index=i; temp.hasheds=hashuj(now); temp.nacin=-1; temp.solution=""; temp.brmax=100; if(temp.n<=30)temp.brmax=1000; else if(temp.n<=80)temp.brmax=200; else if(temp.n<=150)temp.brmax=120; maxi=max(maxi,temp.n); suman+=temp.n; reci.pb(temp); } vremePoSlovu = timelimit/(double)suman; sort(reci.begin(),reci.end(),cmpbegin); nacini(); if(t!=2 && maxi<=400){ resi3(); } for(int i=0;i