結果
問題 |
No.1743 Permutation Code
|
ユーザー |
![]() |
提出日時 | 2025-05-14 13:05:05 |
言語 | C++17 (gcc 13.3.0 + boost 1.87.0) |
結果 |
TLE
|
実行時間 | - |
コード長 | 8,020 bytes |
コンパイル時間 | 641 ms |
コンパイル使用メモリ | 83,688 KB |
実行使用メモリ | 16,064 KB |
最終ジャッジ日時 | 2025-05-14 13:07:01 |
合計ジャッジ時間 | 10,983 ms |
ジャッジサーバーID (参考情報) |
judge5 / judge4 |
(要ログイン)
ファイルパターン | 結果 |
---|---|
other | AC * 7 TLE * 1 -- * 22 |
ソースコード
#include <iostream> #include <vector> #include <string> #include <numeric> #include <algorithm> #include <string_view> // Use string_view for efficiency to avoid copying substrings // Global variables to store the state accessible by the recursive function std::string C; // The concatenated binary string input int N; // The size of the permutation (numbers 1 to N) std::vector<bool> available; // Tracks which numbers from 1 to N are still available to be used std::vector<int> result_permutation; // Stores the permutation being built / the final result int max_len_N; // The maximum possible bit length for any number up to N /** * @brief Converts a binary string (represented by string_view) to its decimal integer value. * * @param bin_sv A string_view representing the binary string. Must contain only '0' and '1'. * @return The decimal value of the binary string. */ long long binToDecView(std::string_view bin_sv) { long long dec = 0; // Efficient conversion using bit shifts. // Assumes input contains only '0' and '1'. // The maximum value N=65535 (16 bits) fits well within long long (64 bits). for (char c : bin_sv) { dec = (dec << 1) | (c - '0'); } return dec; } /** * @brief The recursive backtracking function to find a valid permutation. * * @param index The current starting index in the concatenated string C to parse from. * @return True if a valid permutation is found from this state, False otherwise. */ bool solve(int index) { // Base case: If we have successfully parsed the entire string C if (index == C.length()) { // A valid partition covers the entire string C. // We also need to ensure exactly N numbers were used. // This check confirms we formed a complete permutation of 1..N. return result_permutation.size() == N; } // Determine the maximum length for the next binary string segment we can try. // It cannot be longer than the remaining part of C, nor longer than the maximum // bit length required for any number up to N. int current_max_len = std::min(max_len_N, (int)C.length() - index); // Iterate through all possible lengths `l` for the next number's binary representation. for (int l = 1; l <= current_max_len; ++l) { // Extract the substring of length `l` starting at `index`. // Use string_view to avoid expensive string copying. std::string_view sub = std::string_view(C).substr(index, l); // The binary representation of any integer P_i >= 1 must start with '1' // (no leading zeros allowed). Check this condition. if (sub[0] == '0') continue; // Skip if it starts with '0' // Convert the binary substring `sub` to its integer value `k`. long long k_ll = binToDecView(sub); // Check if the obtained integer `k` is valid for the permutation: // 1. Must be positive (i.e., >= 1). // 2. Must not exceed N (the upper bound of the permutation range). if (k_ll <= 0 || k_ll > N) { continue; // k is outside the valid range {1, ..., N} } int k = (int)k_ll; // Safe to cast to int because 1 <= k_ll <= N <= 65535 fits in standard int. // Check if the number `k` is available (i.e., hasn't been used yet in the permutation) if (available[k]) { // Try including k in the permutation available[k] = false; // Mark k as used result_permutation.push_back(k); // Add k to the current sequence being built // Recursively call solve for the remainder of the string C, starting after the current segment. if (solve(index + l)) { // If the recursive call finds a solution, it means we found a valid complete permutation. // Propagate true up the call stack. return true; } // Backtrack: If the choice of `k` did not lead to a solution, undo the choice. result_permutation.pop_back(); // Remove k from the sequence available[k] = true; // Mark k as available again, allowing other paths to use it. } } // If we tried all possible lengths `l` from the current `index` and none led to a solution, // then this path is invalid. Return false. return false; } /** * @brief Calculates the number of bits in the binary representation of integer k (without leading zeros). * Equivalent to floor(log2(k)) + 1 for k > 0. * * @param k The positive integer. * @return The number of bits required. Returns 0 for k <= 0. */ long long integer_bit_length(int k) { if (k <= 0) return 0; // Bit length is defined for positive integers. // Calculate bit length using integer operations (safer than float log2). long long len = 0; unsigned int tempK = k; // Use unsigned type for right bit shifts to avoid potential sign extension issues. while (tempK > 0) { tempK >>= 1; // Right shift by 1 is equivalent to dividing by 2. len++; } // Example: k=1 (0b1) -> len=1. k=2 (0b10) -> len=2. k=3 (0b11) -> len=2. k=4 (0b100) -> len=3. // This correctly computes the number of bits. return len; } int main() { // Use fast I/O operations for performance critical competitive programming tasks. std::ios_base::sync_with_stdio(false); std::cin.tie(NULL); std::cin >> C; // Read the concatenated binary string input C. long long target_len = C.length(); // The required total length of concatenated binary strings. // Problem constraints state |C| >= 1, so target_len will be at least 1. // Determine the value of N by summing the bit lengths of integers 1, 2, ..., N // until the total length matches target_len. long long current_len = 0; N = 0; // Start counting N from 1. while(current_len < target_len) { N++; // Basic check to prevent infinite loop or overflow if N becomes unexpectedly large. // Maximum N is 65535 based on max |C|, safely within int range. if (N <= 0) return 1; // Error state check. current_len += integer_bit_length(N); // Add the bit length of the current number N. } // Verify that the calculated total length matches the input string length. // The problem guarantees that such an N exists and a permutation can be formed. if (current_len != target_len) { // This case indicates an inconsistency, potentially a bug or misinterpretation. // According to the problem, this should not happen. return 1; // Exit with error code. } // Calculate the maximum bit length required for any number in the range 1..N. // This is simply the bit length of N itself. max_len_N = integer_bit_length(N); // Initialize data structures needed for the backtracking search. // `available` vector tracks usage of numbers 1 to N. Size N+1 for 1-based indexing. available.resize(N + 1, true); available[0] = false; // Index 0 is unused. // `result_permutation` will store the found sequence. Reserve space for N elements // to potentially improve performance by avoiding reallocations during push_back. result_permutation.reserve(N); // Start the backtracking search from the beginning of the string C (index 0). if (!solve(0)) { // If solve(0) returns false, it means no solution was found. // This contradicts the problem statement's guarantee that a solution exists. // Indicates a potential issue with the logic or implementation. return 1; // Exit with error code. } // Print the found permutation elements, separated by spaces. for (int i = 0; i < result_permutation.size(); ++i) { std::cout << result_permutation[i] << (i == result_permutation.size() - 1 ? "" : " "); } std::cout << std::endl; // Ensure the output ends with a newline character. return 0; // Indicate successful execution. }