結果
| 問題 | No.506 限られたジャパリまん | 
| コンテスト | |
| ユーザー |  qwewe | 
| 提出日時 | 2025-05-14 13:13:20 | 
| 言語 | C++17 (gcc 13.3.0 + boost 1.87.0) | 
| 結果 | 
                                WA
                                 
                             | 
| 実行時間 | - | 
| コード長 | 7,057 bytes | 
| コンパイル時間 | 853 ms | 
| コンパイル使用メモリ | 88,972 KB | 
| 実行使用メモリ | 7,844 KB | 
| 最終ジャッジ日時 | 2025-05-14 13:14:18 | 
| 合計ジャッジ時間 | 7,317 ms | 
| ジャッジサーバーID (参考情報) | judge5 / judge3 | 
(要ログイン)
| ファイルパターン | 結果 | 
|---|---|
| other | AC * 12 WA * 13 | 
ソースコード
#include <iostream>
#include <vector>
#include <string>
#include <numeric> // Not strictly needed, but good practice for potentially using standard algorithms
#include <algorithm> // For std::max, though manual comparison is used here
#include <vector>
// Use __builtin_popcount if available (typically on GCC/Clang)
#if defined(__GNUC__) || defined(__clang__)
#define USE_BUILTIN_POPCOUNT
#endif
using namespace std;
// Define long long for convenience, especially for path counts that can exceed 32-bit int limits
typedef long long ll;
ll H, W; // Grid dimensions (East-West H meters, North-South W meters)
int K; // Number of friends
int P; // Number of Japari buns available
// Structure to store friend information
struct FriendInfo {
    int x, y; // Coordinates of the friend
    string name; // Name of the friend
};
vector<FriendInfo> friends; // Vector to store information about all K friends
ll MOD = 1000000007; // Modulo value for path counting
// Function to count set bits (population count) in an integer
// This determines how many friends are chosen in a subset represented by a bitmask
int countSetBits(int n) {
#ifdef USE_BUILTIN_POPCOUNT
    // Use the compiler's built-in function for efficiency if available
    return __builtin_popcount(n);
#else
    // Fallback manual implementation using Brian Kernighan's algorithm
    // Works for non-negative integers
    int count = 0;
    unsigned int val = static_cast<unsigned int>(n); // Use unsigned int for safety with bitwise ops
    while (val > 0) {
        val &= (val - 1); // Clears the least significant set bit
        count++;
    }
    return count;
#endif
}
// Dynamic Programming function to calculate the number of shortest paths
// from (0,0) to (H,W) for a given subset of friends allowed to pass (represented by mask).
// Friends whose corresponding bit in 'mask' is 1 are passable. Others are obstacles.
ll calculate_paths(int mask) {
    // Create a grid to mark obstacle locations. True if obstacle, false otherwise.
    vector<vector<bool>> is_obstacle(H + 1, vector<bool>(W + 1, false));
    for (int i = 0; i < K; ++i) {
        // If the i-th bit in the mask is 0, this friend is NOT given a bun and acts as an obstacle.
        if (!((mask >> i) & 1)) {
             // Mark the friend's location as an obstacle
             // The problem guarantees friend coordinates are within grid bounds [0,H] x [0,W]
             is_obstacle[friends[i].x][friends[i].y] = true;
        }
    }
    // DP table: dp[x][y] will store the number of shortest paths from (0,0) to (x,y)
    vector<vector<ll>> dp(H + 1, vector<ll>(W + 1, 0));
    // Base case: The starting point (0,0).
    // The problem states (0,0) is never an obstacle location.
    if (is_obstacle[0][0]) return 0; // Safety check: if start is blocked, 0 paths.
    dp[0][0] = 1; // There is one way to be at the start: just be there.
    // Fill the DP table iteratively
    for (int x = 0; x <= H; ++x) {
        for (int y = 0; y <= W; ++y) {
            
            // If the current cell (x,y) is an obstacle, no paths can go through it.
            if (is_obstacle[x][y]) {
                dp[x][y] = 0; // Ensure dp value is 0 for obstacles
                continue; // Skip calculation for this cell, paths cannot terminate or pass through here.
            }
            // For non-obstacle cells, calculate paths reaching it.
            // Paths can only come from the West (x-1, y) or South (x, y-1).
            
            // Add paths coming from West (moving East to reach (x,y))
            if (x > 0) {
                 // We add dp[x-1][y] because any path to (x-1,y) can be extended East to (x,y).
                 // No need to check if (x-1, y) is obstacle, as if it were, dp[x-1][y] would be 0.
                 dp[x][y] = (dp[x][y] + dp[x-1][y]) % MOD; 
            }
            // Add paths coming from South (moving North to reach (x,y))
            if (y > 0) {
                 // Similarly, add dp[x][y-1]
                 dp[x][y] = (dp[x][y] + dp[x][y-1]) % MOD;
            }
            // Note: The base case dp[0][0]=1 is correctly handled. dp[1][0] will get value from dp[0][0],
            // dp[0][1] will get value from dp[0][0]. dp[1][1] will get value from dp[0][1] and dp[1][0].
        }
    }
    // The final answer for this mask is the number of paths to the destination (H, W).
    return dp[H][W];
}
int main() {
    // Use faster I/O operations
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    // Read input values: grid dimensions H, W, number of friends K, number of buns P
    cin >> H >> W >> K >> P;
    // Read friend data: coordinates (x,y) and name for each friend
    friends.resize(K);
    for (int i = 0; i < K; ++i) {
        cin >> friends[i].x >> friends[i].y >> friends[i].name;
    }
    ll max_paths = -1; // Initialize max_paths to -1 to track the maximum paths found so far.
                       // -1 helps distinguish between 0 paths and initial state.
    int best_mask = -1; // Initialize best_mask to -1, stores the mask yielding max_paths.
    // Iterate through all possible subsets of friends using bitmasks from 0 to 2^K - 1
    for (int mask = 0; mask < (1 << K); ++mask) {
        // A subset is valid if the number of friends chosen (number of set bits) is at most P.
        if (countSetBits(mask) <= P) {
            // Calculate the number of shortest paths for the current subset choice.
            ll current_paths = calculate_paths(mask);
            
            // If the number of paths for this subset is greater than the current maximum found:
            if (current_paths > max_paths) {
                max_paths = current_paths; // Update the maximum path count.
                best_mask = mask;         // Update the mask that achieved this maximum.
            }
        }
    }
    
    // --- Output Results ---
    // If max_paths is still -1 (should technically not happen for H, W >= 1 as (0,0) is reachable)
    // or if max_paths is 0, it means the destination (H,W) is unreachable for all valid subsets.
    // In this case, output 0 as required.
    if (max_paths <= 0) { 
        cout << 0 << endl; 
    } else {
        // Otherwise, output the maximum number of paths found.
        cout << max_paths << endl;
        
        // Then, output the names of the friends corresponding to the set bits in the best_mask.
        // Iterate through friends based on their original input order (index i).
        for (int i = 0; i < K; ++i) {
           // Check if the i-th bit is set in the best_mask.
           if ((best_mask >> i) & 1) {
               // If set, this friend was given a bun in the optimal solution. Print their name.
               cout << friends[i].name << endl;
           }
        }
    }
    
    // The problem statement asks for a final newline. Standard output with `endl` handles newlines after each print.
    // No extra blank line is typically needed unless explicitly specified.
    return 0; // Indicate successful execution
}
            
            
            
        