Advertisement
coloriot

HA_17B_V2

Jul 30th, 2024
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.87 KB | None | 0 0
  1. #include <iostream>
  2.  
  3. using namespace std;
  4.  
  5. class String {
  6. private:
  7.     char* data;
  8.     int length;
  9.  
  10. public:
  11.     String() : data(nullptr), length(0) {}
  12.  
  13.     String(const char* str, int len) : length(len) {
  14.         data = new char[length];
  15.         for (int i = 0; i < length; i++) {
  16.             data[i] = str[i];
  17.         }
  18.     }
  19.  
  20.     String(const String& other) : length(other.length) {
  21.         data = new char[length];
  22.         for (int i = 0; i < length; i++) {
  23.             data[i] = other.data[i];
  24.         }
  25.     }
  26.  
  27.     ~String() { // Деструктор
  28.         delete[] data;
  29.     }
  30.  
  31.     String& operator=(const String& other) {
  32.         if (this == &other)
  33.             return *this;
  34.  
  35.         delete[] data;
  36.         length = other.length;
  37.         data = new char[length];
  38.         for (int i = 0; i < length; i++) {
  39.             data[i] = other.data[i];
  40.         }
  41.         return *this;
  42.     }
  43.  
  44.     bool startsWith(const String& prefix) const {
  45.         if (prefix.length > length)
  46.             return false;
  47.  
  48.         for (int i = 0; i < prefix.length; i++) {
  49.             if (data[i] != prefix.data[i])
  50.                 return false;
  51.         }
  52.         return true;
  53.     }
  54.  
  55.     bool operator<(const String& other) const {
  56.         int minLength = length < other.length ? length : other.length;
  57.         for (int i = 0; i < minLength; i++) {
  58.             if (data[i] < other.data[i])
  59.                 return true;
  60.  
  61.             if (data[i] > other.data[i])
  62.                 return false;
  63.         }
  64.         return length < other.length;
  65.     }
  66.  
  67.     bool operator==(const String& other) const {
  68.         if (length != other.length)
  69.             return false;
  70.  
  71.         for (int i = 0; i < length; i++) {
  72.             if (data[i] != other.data[i])
  73.                 return false;
  74.         }
  75.         return true;
  76.     }
  77.  
  78.     int size() const {
  79.         return length;
  80.     }
  81.  
  82.     char operator[](int index) const {
  83.         return data[index];
  84.     }
  85.  
  86.     friend istream& operator>>(istream& is, String& str) {
  87.         string buffer;
  88.         is >> buffer;
  89.         str = String(buffer.data(), buffer.size());
  90.         return is;
  91.     }
  92.  
  93.     friend ostream& operator<<(ostream& os, const String& str) {
  94.         for (int i = 0; i < str.length; i++) {
  95.             os << str.data[i];
  96.         }
  97.         return os;
  98.     }
  99. };
  100.  
  101. // Функция для нахождения середины
  102. int findMidpoint(int left, int right) {
  103.     return (left + right) / 2;
  104. }
  105.  
  106. int main() {
  107.     int N, Q;
  108.     cin >> N >> Q;
  109.  
  110.     String* dictionary = new String[N];
  111.     for (int i = 0; i < N; ++i) {
  112.         cin >> dictionary[i];
  113.     }
  114.  
  115.     int* results = new int[Q];
  116.  
  117.     for (int i = 0; i < Q; ++i) {
  118.         String prefix;
  119.         int k;
  120.         cin >> k >> prefix;
  121.  
  122.         int count = 0;
  123.         results[i] = -1;
  124.  
  125.         int left = 0, right = N;
  126.  
  127.         // Поиск за O(lgn):
  128.         while (left < right) {
  129.             int mid = findMidpoint(left, right);
  130.             if (dictionary[mid].startsWith(prefix)) {
  131.                 right = mid;
  132.             } else if (dictionary[mid] < prefix) {
  133.                 left = mid + 1;
  134.             } else {
  135.                 right = mid;
  136.             }
  137.         }
  138.  
  139.         // Подсчет строк, начинающихся с префикса
  140.         for (int j = left; j < N; ++j) {
  141.             if (dictionary[j].startsWith(prefix)) {
  142.                 count++;
  143.                 if (count == k) { // Если найдена k-я строка
  144.                     results[i] = j + 1;
  145.                     break;
  146.                 }
  147.             } else {
  148.                 break; // Прекращение поиска
  149.             }
  150.         }
  151.     }
  152.  
  153.     for (int i = 0; i < Q; ++i) {
  154.         cout << results[i] << '\n'; // Вывод результатов
  155.     }
  156.  
  157.     delete[] dictionary;
  158.     delete[] results;
  159.  
  160.     return 0;
  161. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement