E - 暗号変換装置とパスワード認証 / Cipher Conversion Device and Password Authentication 解説 by admin
Claude 4.6 Opus (Thinking)Overview
This problem asks us to optimally choose how to fill in the undetermined positions of password \(S\) and the order of transmission to \(N\) agents, maximizing the number of successful authentications. Given the constraint \(N \leq 8\), we can exhaustively search all transmission orders (\(N!\) possibilities).
Analysis
Key Insight ①: Fixing the transmission order determines the transformation for each agent
Once we fix the transmission order \((\sigma_1, \sigma_2, \dots, \sigma_N)\), the cumulative transformation \(C^{(m)}\) at the time of sending to the \(m\)-th agent is uniquely determined.
- \(C^{(1)} = \text{id}\) (identity permutation)
- \(C^{(m+1)} = A_{\sigma_m} \circ C^{(m)}\)
Key Insight ②: The authentication success condition can be converted to a constraint on \(S\)
The condition for agent \(\sigma_m\)’s authentication to succeed is that \(C^{(m)}_{S_j} = T_{\sigma_m, j}\) holds for all positions \(j\). This is equivalent to:
\[S_j = (C^{(m)})^{-1}(T_{\sigma_m, j})\]
In other words, the success condition for each agent takes the form “S equals some specific sequence \(R^{(m)}\)”.
Key Insight ③: Condition for multiple agents to succeed simultaneously
Since \(S\) cannot be changed once determined, multiple agents can succeed simultaneously only when all their required sequences \(R^{(m)}\) are identical.
Key Insight ④: Whether the required sequence conflicts with fixed positions \(B\)
At positions where \(B_j \neq 0\), \(S_j = B_j\) is fixed, so if \(R^{(m)}_j \neq B_j\), authentication for that agent is impossible.
Approach
Since \(N \leq 8\), we can exhaustively search all \(N! \leq 40320\) transmission orders. For each transmission order, we compute the required sequence for each agent and find the one that maximizes the number of agents sharing the same required sequence.
Algorithm
- Enumerate all transmission orders: Try all \(N!\) permutations.
- Compute required sequences: For each transmission order, compute the cumulative transformation \(C^{(m)}\) sequentially, and determine the \(m\)-th agent’s required sequence \(R^{(m)}_j = (C^{(m)})^{-1}(T_{\sigma_m, j})\).
- Consistency check with fixed positions: If \(B_j \neq 0\) and \(R^{(m)}_j \neq B_j\), then that agent cannot authenticate (mark as invalid).
- Group by identical required sequences: Among valid agents, find the largest group sharing the same required sequence. The group size is the number of successful agents.
- Track maximum count and lexicographically smallest: Across all transmission orders, record the maximum number of successes and the lexicographically smallest required sequence achieving that maximum.
- Case of 0 successes: Fill fixed positions with \(B_j\) and free positions with \(1\) (minimum value).
Complexity
- Time complexity: \(O(N! \cdot N^2 \cdot L)\)
- \(N! \leq 40320\) permutations, computing \(N\) required sequences per permutation in \(O(NL)\), comparing \(N^2\) pairs of required sequences in \(O(N^2 L)\)
- With \(N=8, L=200\), at most approximately \(5 \times 10^8\) basic operations (acceptable in C++)
- Space complexity: \(O(N \cdot L)\)
Implementation Notes
0-indexed management: Subtract \(1\) from input values to unify as 0-indexed, and add \(+1\) at output.
Inverse permutation computation: Construct the inverse permutation \(C^{(m)}_{inv}\) from \(C^{(m)}\), allowing required sequence computation in \(O(1)\) per element.
Lexicographic comparison: The
<operator between C++vectors directly performs lexicographic comparison, which we can leverage.next_permutation: Use STL’snext_permutationfor enumerating all permutations, keeping the implementation concise.Source Code
#include <bits/stdc++.h>
using namespace std;
int main(){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
int N,K,L;
cin>>N>>K>>L;
vector<int> B(L);
for(int j=0;j<L;j++) cin>>B[j];
vector<vector<int>> T(N,vector<int>(L));
vector<vector<int>> A(N,vector<int>(K));
for(int i=0;i<N;i++){
for(int j=0;j<L;j++){cin>>T[i][j]; T[i][j]--;}
for(int k=0;k<K;k++){cin>>A[i][k]; A[i][k]--;}
}
int best_count=0;
vector<int> best_S;
vector<int> order(N);
iota(order.begin(),order.end(),0);
do {
vector<int> C(K);
iota(C.begin(),C.end(),0);
vector<vector<int>> reqs;
vector<bool> valid_flags;
for(int m=0;m<N;m++){
int agent=order[m];
vector<int> C_inv(K);
for(int k=0;k<K;k++) C_inv[C[k]]=k;
vector<int> req(L);
bool ok=true;
for(int j=0;j<L;j++){
req[j]=C_inv[T[agent][j]];
if(B[j]!=0 && req[j]!=B[j]-1){
ok=false;
break;
}
}
reqs.push_back(req);
valid_flags.push_back(ok);
// Update C: C' = A[agent] ∘ C
vector<int> newC(K);
for(int k=0;k<K;k++) newC[k]=A[agent][C[k]];
C=newC;
}
// Group valid agents by requirement
for(int m=0;m<N;m++){
if(!valid_flags[m]) continue;
int cnt=0;
for(int m2=0;m2<N;m2++){
if(!valid_flags[m2]) continue;
if(reqs[m]==reqs[m2]) cnt++;
}
if(cnt>best_count||(cnt==best_count&&(best_S.empty()||reqs[m]<best_S))){
best_count=cnt;
best_S=reqs[m];
}
}
} while(next_permutation(order.begin(),order.end()));
if(best_count==0){
best_S.resize(L);
for(int j=0;j<L;j++){
if(B[j]!=0) best_S[j]=B[j]-1;
else best_S[j]=0;
}
}
cout<<best_count<<"\n";
for(int j=0;j<L;j++){
cout<<best_S[j]+1<<" \n"[j==L-1];
}
return 0;
}
This editorial was generated by claude4.6opus-thinking.
投稿日時:
最終更新: