CodeChef submission 136789 (C) plaintext list. Status: CE, problem SNCK03, contest SNACKDWN. By haymakers (haymakers), 2009-11-21 23:57:26.
/* * perm.cpp * * * Created by Mayank Jaiswal on 21/11/09. * Copyright 2009 IIT Kharagpur. All rights reserved. * */ using namespace std; //using namespace stdcomb; #include<iostream> #include<algorithm> #include<vector> #include<set> #define DEBUG false void print(set<int> s) { for(set<int> :: iterator p= s.begin(); p!= s.end() ; p++) if(DEBUG) cout<< *p<< " "; if(DEBUG) cout<< endl; } void print(vector<int> s) { for(int i=0; i<s.size(); i++) if(DEBUG) cout<< s[i]<< " "; if(DEBUG) cout<< endl; } //======================================================= // combination.h // Description : Template class to find combinations //======================================================= // Copyright 2003 - 2006 Wong Shao Voon // No warranty, implied or expressed, is included. // Author is not liable for any type of loss through // the use of this source code. Use it at your own risk! //======================================================= #ifndef __COMBINATION_H__ #define __COMBINATION_H__ namespace stdcomb { // Non recursive template function template <class BidIt> inline bool next_combination(BidIt n_begin, BidIt n_end, BidIt r_begin, BidIt r_end) { bool boolmarked=false; BidIt r_marked; BidIt n_it1=n_end; --n_it1; BidIt tmp_r_end=r_end; --tmp_r_end; for(BidIt r_it1=tmp_r_end; r_it1!=r_begin || r_it1==r_begin; --r_it1,--n_it1) { if(*r_it1==*n_it1 ) { if(r_it1!=r_begin) //to ensure not at the start of r sequence { boolmarked=true; r_marked=(--r_it1); ++r_it1;//add it back again continue; } else // it means it is at the start the sequence, so return false return false; } else //if(*r_it1!=*n_it1 ) { //marked code if(boolmarked==true) { //for loop to find which marked is in the first sequence BidIt n_marked;//mark in first sequence for (BidIt n_it2=n_begin;n_it2!=n_end;++n_it2) if(*r_marked==*n_it2) {n_marked=n_it2;break;} BidIt n_it3=++n_marked; for (BidIt r_it2=r_marked;r_it2!=r_end;++r_it2,++n_it3) { *r_it2=*n_it3; } return true; } for(BidIt n_it4=n_begin; n_it4!=n_end; ++n_it4) if(*r_it1==*n_it4) { *r_it1=*(++n_it4); return true; } } } return true;//will never reach here } // Non recursive template function with Pred template <class BidIt, class Prediate> inline bool next_combination( BidIt n_begin, BidIt n_end, BidIt r_begin, BidIt r_end, Prediate Equal) { bool boolmarked=false; BidIt r_marked; BidIt n_it1=n_end; --n_it1; BidIt tmp_r_end=r_end; --tmp_r_end; for(BidIt r_it1=tmp_r_end; r_it1!=r_begin || r_it1==r_begin; --r_it1,--n_it1) { if( Equal( *r_it1, *n_it1) ) { if(r_it1!=r_begin) //to ensure not at the start of r sequence { boolmarked=true; r_marked=(--r_it1); ++r_it1;//add it back again continue; } else // it means it is at the start the sequence, so return false return false; } else //if(*r_it1!=*n_it1 ) { //marked code if(boolmarked==true) { //for loop to find which marked is in the first sequence BidIt n_marked;//mark in first sequence for (BidIt n_it2=n_begin;n_it2!=n_end;++n_it2) if( Equal( *r_marked, *n_it2) ) {n_marked=n_it2;break;} BidIt n_it3=++n_marked; for (BidIt r_it2=r_marked;r_it2!=r_end;++r_it2,++n_it3) { *r_it2=*n_it3; } return true; } for(BidIt n_it4=n_begin; n_it4!=n_end; ++n_it4) if( Equal(*r_it1, *n_it4) ) { *r_it1=*(++n_it4); return true; } } } return true;//will never reach here } // Non recursive template function template <class BidIt> inline bool prev_combination(BidIt n_begin, BidIt n_end, BidIt r_begin, BidIt r_end) { bool boolsame=false; BidIt marked;//for r BidIt r_marked; BidIt n_marked; BidIt tmp_n_end=n_end; --tmp_n_end; BidIt r_it1=r_end; --r_it1; for(BidIt n_it1=tmp_n_end; n_it1!=n_begin || n_it1==n_begin ; --n_it1) { if(*r_it1==*n_it1) { r_marked=r_it1; n_marked=n_it1; break; } } BidIt n_it2=n_marked; BidIt tmp_r_end=r_end; --tmp_r_end; for(BidIt r_it2=r_marked; r_it2!=r_begin || r_it2==r_begin; --r_it2,--n_it2) { if(*r_it2==*n_it2 ) { if(r_it2==r_begin&& !(*r_it2==*n_begin) ) { for(BidIt n_it3=n_begin;n_it3!=n_end;++n_it3) { if(*r_it2==*n_it3) { marked=r_it2; *r_it2=*(--n_it3); BidIt n_it4=n_end; --n_it4; for(BidIt r_it3=tmp_r_end; (r_it3!=r_begin || r_it3==r_begin) &&r_it3!=marked; --r_it3,--n_it4) { *r_it3=*n_it4; } return true; } } } else if(r_it2==r_begin&&*r_it2==*n_begin) { return false;//no more previous combination; } } else //if(*r_it2!=*n_it2 ) { ++r_it2; marked=r_it2; for(BidIt n_it5=n_begin;n_it5!=n_end;++n_it5) { if(*r_it2==*n_it5) { *r_it2=*(--n_it5); BidIt n_it6=n_end; --n_it6; for(BidIt r_it4=tmp_r_end; (r_it4!=r_begin || r_it4==r_begin) &&r_it4!=marked; --r_it4,--n_it6) { *r_it4=*n_it6; } return true; } } } } return false;//Will never reach here, unless error } // Non recursive template function with Pred template <class BidIt, class Prediate> inline bool prev_combination( BidIt n_begin, BidIt n_end, BidIt r_begin, BidIt r_end, Prediate Equal) { bool boolsame=false; BidIt marked;//for r BidIt r_marked; BidIt n_marked; BidIt tmp_n_end=n_end; --tmp_n_end; BidIt r_it1=r_end; --r_it1; for(BidIt n_it1=tmp_n_end; n_it1!=n_begin || n_it1==n_begin ; --n_it1) { if( Equal(*r_it1, *n_it1) ) { r_marked=r_it1; n_marked=n_it1; break; } } BidIt n_it2=n_marked; BidIt tmp_r_end=r_end; --tmp_r_end; for(BidIt r_it2=r_marked; r_it2!=r_begin || r_it2==r_begin; --r_it2,--n_it2) { if( Equal(*r_it2, *n_it2) ) { if(r_it2==r_begin&& !Equal(*r_it2, *n_begin) ) { for(BidIt n_it3=n_begin;n_it3!=n_end;++n_it3) { if(Equal(*r_it2, *n_it3)) { marked=r_it2; *r_it2=*(--n_it3); BidIt n_it4=n_end; --n_it4; for(BidIt r_it3=tmp_r_end; (r_it3!=r_begin || r_it3==r_begin) &&r_it3!=marked; --r_it3,--n_it4) { *r_it3=*n_it4; } return true; } } } else if(r_it2==r_begin&&Equal(*r_it2, *n_begin)) { return false;//no more previous combination; } } else //if(*r_it2!=*n_it2 ) { ++r_it2; marked=r_it2; for(BidIt n_it5=n_begin;n_it5!=n_end;++n_it5) { if(Equal(*r_it2, *n_it5)) { *r_it2=*(--n_it5); BidIt n_it6=n_end; --n_it6; for(BidIt r_it4=tmp_r_end; (r_it4!=r_begin || r_it4==r_begin) &&r_it4!=marked; --r_it4,--n_it6) { *r_it4=*n_it6; } return true; } } } } return false;//Will never reach here, unless error } // Recursive template function template <class RanIt, class Func> void recursive_combination(RanIt nbegin, RanIt nend, int n_column, RanIt rbegin, RanIt rend, int r_column,int loop, Func func) { int r_size=rend-rbegin; int localloop=loop; int local_n_column=n_column; //A different combination is out if(r_column>(r_size-1)) { func(rbegin,rend); return; } ///////////////////////////////// for(int i=0;i<=loop;++i) { RanIt it1=rbegin; for(int cnt=0;cnt<r_column;++cnt) { ++it1; } RanIt it2=nbegin; for(int cnt2=0;cnt2<n_column+i;++cnt2) { ++it2; } *it1=*it2; ++local_n_column; recursive_combination(nbegin,nend,local_n_column, rbegin,rend,r_column+1,localloop,func); --localloop; } } } #endif // for use with next_combination examples! template<class BidIt> void display(BidIt begin,BidIt end) { for (BidIt it=begin;it!=end;++it) if(DEBUG) cout<<*it<<" "; if(DEBUG) cout<<endl; } int perm(int cse, vector<int> list , int prev, vector<int> B ) { int count=0; if(DEBUG) cout<< " list: "; for (int i=0; i<list.size(); i++) if(DEBUG) cout<< " B: "; for (int i=0; i<B.size(); i++) if(cse==B.size()) { return 1; } int dec= cse%2; if(dec==0) // increasing { /* //inserting in set set<int> listset; for (int i=0; i<list.size(); i++) listset.insert(list[i]); if(DEBUG) cout<< "set: "; for (set<int> :: iterator p = listset.begin(); p!= listset.end(); p++) if(DEBUG) cout << *p<<" "; if(DEBUG) cout << endl; */ vector <int> smallListOptions; for (int i=0; i<list.size(); i++) if(list[i]>prev) smallListOptions.push_back(list[i]); if(smallListOptions.size() < B[cse]-1) return 0; vector<int> smallList; for(int i=0; i<B[cse]-1;i++) smallList.push_back(smallListOptions[i]); for(int i=0; i<smallList.size();i++) if(DEBUG) cout<< smallList[i]<< " "; if(DEBUG) cout<<endl; do { display(smallList.begin(),smallList.end()); set<int> listset; for (int i=0; i<list.size(); i++) listset.insert(list[i]); for (int i=0; i<smallList.size(); i++) listset.erase(smallList[i]); vector<int> restlist; for (set<int> :: iterator p = listset.begin(); p!= listset.end(); p++) restlist.push_back(*p); for (int i=0; i<restlist.size(); i++) if(DEBUG) cout<< restlist[i]<< " "; count += perm(cse+1, restlist, smallList[smallList.size()-1],B); // int perm(int cse, vector<int> list , int prev, vector<int> B ) //****************************** } while(stdcomb::next_combination(smallListOptions.begin (),smallListOptions.end (),smallList.begin (),smallList.end()) ); return count; } else if(dec==1) //decreasing { vector <int> smallListOptions; for (int i=0; i<list.size(); i++) if(list[i]<prev) smallListOptions.push_back(list[i]); print(smallListOptions); if(smallListOptions.size() < B[cse]-1) return 0; vector<int> smallList; for(int i=0; i<B[cse]-1;i++) smallList.push_back(smallListOptions[i]); for(int i=0; i<smallList.size();i++) if(DEBUG) cout<< smallList[i]<< " "; if(DEBUG) cout<<endl; do { display(smallList.begin(),smallList.end()); set<int> listset; if(list.size()!=0) for (int i=0; i<list.size(); i++) listset.insert(list[i]); print(listset); if(smallList.size()!=0) for (int i=0; i<smallList.size(); i++) listset.erase(smallList[i]); print(smallList); vector<int> restlist; for (set<int> :: iterator p = listset.begin(); p!= listset.end(); p++) restlist.push_back(*p); print(restlist); count += perm(cse+1, restlist, smallList[0],B); // int perm(int cse, vector<int> list , int prev, vector<int> B ) //****************************** } while(stdcomb::next_combination(smallListOptions.begin (),smallListOptions.end (),smallList.begin (),smallList.end()) ); return count; } } int main() { int T; cin>> T; for(int test=1; test<=T ; test++ ) { int N; int K; cin >> N; cin >> K; vector<int> list ; //input list for (int i=0; i<K; i++) { int temp; cin>>temp; list.push_back(temp); } for (int i=0; i<list.size(); i++) //creating B vector<int> B; for(int i=0; i<K-1; i++) B.push_back(list[i+1]-list[i]+1); for (int i=0; i<B.size(); i++) // for (int i=1; i<=N; i++) // list.push_back(i); int count=0; for (int i=1; i<=N; i++) { list.erase (list.begin(),list.end()); for (int j=1; j<=N; j++) { if(j!=i) list.push_back(j); } count += perm(0,list,i ,B); } // printf("Case #%2d :%d\n\n\n",test, count); } return 0; } // // perm(2,list,4);
Comments

