제출 #1162620

#제출 시각아이디문제언어결과실행 시간메모리
1162620cnn008Password (RMI18_password)C11
0 / 100
48 ms464 KiB
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdbool.h> #include <assert.h> // Declaration of query. This must be defined elsewhere. int query(const char *p); //---------------------------------------------------------------- // Helper function: ck // This function builds a temporary string t as follows: // 1. t[0] is the character c. // 2. For indices 0 to (ans_len - l - 1) of ans, if ans[i]==c, append c. // 3. Then append ans[i] for i from (ans_len - l) to (ans_len - 1). // It returns true if query(t) equals the length of t. static bool ck(char c, int l, const char *ans, int ans_len) { // Maximum possible length of t is (ans_len + 1) int t_buf_size = ans_len + 2; char *t_buf = malloc(t_buf_size); if (!t_buf) { fprintf(stderr, "malloc failed in ck\n"); exit(1); } int t_len = 0; t_buf[t_len++] = c; // Append copies of c for every ans[i]==c in the first part. for (int i = 0; i < ans_len - l; i++) { if (ans[i] == c) { t_buf[t_len++] = c; } } // Append the tail of ans. for (int i = ans_len - l; i < ans_len; i++) { t_buf[t_len++] = ans[i]; } t_buf[t_len] = '\0'; int res = query(t_buf); free(t_buf); return (res == t_len); } //---------------------------------------------------------------- // Function: guess // Parameters: // n - the final length of the answer string // s - the number of distinct letters to consider (assumed to be consecutive letters starting from 'a') // Returns a malloc’ed string of length n (caller is responsible for freeing it). char* guess(int n, int s) { // Allocate buffer for the final answer; we build it gradually. char *ans = malloc(n + 1); if (!ans) { fprintf(stderr, "malloc failed for ans\n"); exit(1); } int ans_len = 0; // Allocate and zero-initialize an array of s integers. int *cnt = calloc(s, sizeof(int)); if (!cnt) { fprintf(stderr, "calloc failed for cnt\n"); exit(1); } // For each letter from 'a' to 'a' + s - 1, try to build a string "cur" of that letter. for (int i = 0; i < s; i++) { char c = 'a' + i; char cur[n + 1]; // temporary buffer (max length n) int cur_len = 0; while (cur_len < n) { cur[cur_len] = c; cur[cur_len + 1] = '\0'; if (query(cur) != cur_len + 1) { break; } cur_len++; } cnt[i] = cur_len; } // Find the first letter that produced a nonzero count. int st = -1; for (int i = 0; i < s; i++) { if (cnt[i] != 0) { char c = 'a' + i; for (int j = 0; j < cnt[i]; j++) { ans[ans_len++] = c; } st = i; break; } } // For each remaining letter, adjust ans using a binary search strategy. for (int i = st + 1; i < s; i++) { for (int j = 0; j < cnt[i]; j++) { char c = 'a' + i; int l = 1, r = ans_len, cc = 0; while (l <= r) { int mid = (l + r) / 2; if (ck(c, mid, ans, ans_len)) { cc = mid; l = mid + 1; } else { r = mid - 1; } } // Build the new answer _ans. int new_len = ans_len + 1; char *new_ans = malloc(new_len + 1); if (!new_ans) { fprintf(stderr, "malloc failed for new_ans\n"); exit(1); } int idx = 0; // Copy characters from ans in reverse order from index (ans_len - 1) downto (ans_len - cc). for (int k = ans_len - 1; k >= ans_len - cc; k--) { new_ans[idx++] = ans[k]; } new_ans[idx++] = c; // Copy the remaining part of ans (from index ans_len - cc - 1 downto 0). for (int k = ans_len - cc - 1; k >= 0; k--) { new_ans[idx++] = ans[k]; } // Reverse new_ans to obtain the correct order. for (int k = 0; k < new_len / 2; k++) { char temp = new_ans[k]; new_ans[k] = new_ans[new_len - 1 - k]; new_ans[new_len - 1 - k] = temp; } free(ans); ans = new_ans; ans_len = new_len; } } // Ensure we reached the required length. assert(ans_len == n); ans[ans_len] = '\0'; free(cnt); return ans; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...