Advertisement
a53

Armata Regelui

a53
Aug 15th, 2017
137
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.87 KB | None | 0 0
  1. // autor: Iulia Tamas
  2. #include <fstream>
  3. #include <string.h>
  4. #include <assert.h>
  5.  
  6. #include <string>
  7. #include <set>
  8. #include <vector>
  9. using namespace std;
  10.  
  11. #define A_SIZE 26 // alfabet
  12. #define t_interval pair<pair<char, int>, pair<char, int> >
  13. #define t_intervals vector<t_interval>
  14. #define t_intervals_it vector<t_interval>::iterator
  15.  
  16. char comuta_cu[A_SIZE];
  17. int ss_count[A_SIZE]; // numarul de litere de fiecare fel din ss_config
  18. set<char> ss_in; // literele (trupele) din ss_config
  19. set<int> ss_arc; // pozitiile arcasilor in ss_config
  20. t_intervals ss_ivls;
  21.  
  22. int count[A_SIZE]; // numarul de litere din config curenta
  23.  
  24. void next_interval(string config, int clen, int *start, t_intervals &ivls) {
  25. if (*start >= clen)
  26. return;
  27.  
  28. // calculam descrirea intervalui format doar din literele lit si c_lit
  29. char lit = config[*start];
  30. char c_lit = comuta_cu[lit - 'a'];
  31. int i, n_lit, n_c_lit;
  32. n_lit = 0; // numar de aparitii litera
  33. n_c_lit = 0; // numar de aparitii litera care comuta
  34. for(i = *start; i < clen; i++) {
  35. if(config[i] == lit) {
  36. n_lit++;
  37. continue;
  38. }
  39. if(config[i] == c_lit) {
  40. n_c_lit++;
  41. continue;
  42. }
  43. break;
  44. }
  45.  
  46. ivls.push_back(make_pair(make_pair(lit, n_lit), make_pair(c_lit, n_c_lit)));
  47. *start = i;
  48. }
  49.  
  50. bool equal_intervals(t_interval a, t_interval b) {
  51. return (a.first == b.first && a.second == b.second) ||
  52. (a.first == b.second && a.second == b.first);
  53. }
  54.  
  55. // Prespune: config de lungime corecta
  56. bool same_arc(const string &config) {
  57. set<int>::iterator it;
  58. for(it = ss_arc.begin(); it != ss_arc.end(); it++){
  59. if(config[*it] != 'a')
  60. return false;
  61. }
  62. return true;
  63. }
  64.  
  65. bool same_troups(const string &config) {
  66. memset(count, 0, A_SIZE * sizeof(int));
  67. string::const_iterator sit;
  68. for (sit = config.begin(); sit != config.end(); sit++) {
  69. if (++count[*sit - 'a'] > ss_count[*sit - 'a'])
  70. return false;
  71. }
  72. return true;
  73. }
  74.  
  75. int main() {
  76. fstream fin, fout;
  77. fin.open("armata_regelui.in", fstream::in);
  78. fout.open("armata_regelui.out", fstream::out);
  79.  
  80. // ss_config
  81. string ss_config;
  82. fin >> ss_config;
  83. int ss_len = ss_config.size();
  84.  
  85. // precalculari litere in ss_config
  86. char lit;
  87. string::iterator sit;
  88. memset(comuta_cu, 0, A_SIZE);
  89. memset(ss_count, 0, A_SIZE * sizeof(int));
  90. ss_in.clear();
  91. ss_arc.clear();
  92. for (sit = ss_config.begin(); sit != ss_config.end(); sit++) {
  93. lit = *sit;
  94. assert(lit >= 'a' && lit <= 'z');
  95.  
  96. ss_count[lit - 'a']++;
  97. ss_in.insert(lit);
  98. if (lit == 'a') ss_arc.insert(sit - ss_config.begin());
  99. }
  100.  
  101. // perechi care comuta
  102. int M, N;
  103. char t1, t2;
  104. fin >> M >> N;
  105. for(int i = 0; i < M; i++) {
  106. fin >> t1 >> t2;
  107. comuta_cu[t1 - 'a'] = t2;
  108. comuta_cu[t2 - 'a'] = t1;
  109. }
  110.  
  111. // precalculari intervale in ss_config
  112. int start = 0;
  113. do {
  114. next_interval(ss_config, ss_len, &start, ss_ivls);
  115. } while(start < ss_len);
  116.  
  117. // verificam fiecare configuratie
  118. string config;
  119. t_intervals ivls;
  120. t_intervals_it iit;
  121. for(int i = 1; i <= N; i++){
  122. fin >> config;
  123. int c_len = config.size();
  124. if (c_len != ss_len){
  125. continue;
  126. }
  127.  
  128. // verificam pozitiile arcasilor
  129. if (!same_arc(config)){
  130. continue;
  131. }
  132.  
  133. // verificam numar din fiecare trupa
  134. if (!same_troups(config)){
  135. continue;
  136. }
  137.  
  138. // verificam fiecare interval in parte
  139. ivls.clear();
  140. start = 0;
  141. iit = ss_ivls.begin();
  142. do {
  143. next_interval(config, c_len, &start, ivls);
  144. if(!equal_intervals(ivls.back(), *iit)) {
  145. break;
  146. }
  147.  
  148. iit++;
  149. } while(start < c_len && iit != ss_ivls.end());
  150.  
  151. if(start == c_len && iit == ss_ivls.end()) {
  152. // acelasi numar de intervale si intervalele sunt identice
  153. fout << i << "\n";
  154. }
  155. }
  156.  
  157. fin.close();
  158. fout.close();
  159. return 0;
  160. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement