I somehow ran out of memory and the permutations were not correct in one case.
nocow.cpp
#include <iostream> #include <fstream> #include <set> #include <string> #define loopi(x) loop_start(i,x,0) #define loopj(x) loop_start(j,x,0) #define loop_start(i, x,s) for(int i = (s); i < (x); ++i) #define loop_rev(a,x,stop) for(int a = (x); a >= (stop); --a) using namespace std; int N, K; #define N_MAX 10 #define MAXADJECTIVES 30 #define MAXADJECTIVELEN 10 const char *read_adjective(const char *in, char *out) { for(;;) { // Copy the last character if(*in == '' || *in == ' '){ *out = ''; return in + 1; } // Copy a character *out++ = *in++; } } int main() { ofstream fout ("nocow.out"); ifstream fin ("nocow.in"); // get input // Farmer John has no ___ cow. (19 + ___ + 5 + NULL) char linebuffer[19 + MAXADJECTIVES * MAXADJECTIVELEN + (MAXADJECTIVES-1) + 5 + 1]; fin.getline(linebuffer, sizeof(linebuffer)/sizeof(*linebuffer)); sscanf(linebuffer, "%d %d", &N, &K); --K; // convert to zero-based set<string> adjectives[MAXADJECTIVES]; int num_adjectives = 0; string *removals[N_MAX]; loopi(N) { fin.getline(linebuffer, sizeof(linebuffer)/sizeof(*linebuffer)); const char *p = &linebuffer[19]; // skip "Farmer John has no " char adjective[11]; if(!i) { removals[i] = new string[MAXADJECTIVES]; loopj(MAXADJECTIVES){ p = read_adjective(p, adjective); if(!strcmp(adjective, "cow.")) break; ++num_adjectives; adjectives[j].insert(adjective); removals[i][j] = adjective; } } else{ removals[i] = new string[num_adjectives]; loopj(num_adjectives) { p = read_adjective(p, adjective); adjectives[j].insert(adjective); removals[i][j] = adjective; } } } // calculate positions of the removals and adjust K if needed int offset = 0; int multipliers[N_MAX]; loopi(N){ int position = 0; multipliers[num_adjectives - 1] = 1; loop_rev(j, num_adjectives - 2, 0){ multipliers[j] = multipliers[j + 1] * adjectives[j + 1].size(); } loopj(num_adjectives) position += distance(adjectives[j].begin(), adjectives[j].find(removals[i][j])) * multipliers[j]; if(position <= K) ++offset; } K += offset; // Write output (Kth permutation) loopi(num_adjectives){ if(i) fout << " "; set<string>::iterator it = adjectives[i].begin(); advance(it, (K / multipliers[i]) % adjectives[i].size()); fout << *it; } // Clean up loopi(N) delete[] removals[i]; return 0; }
No comments:
Post a Comment