生成无不动点无碰撞排列矩阵的C代码错误排查及思路验证
First, let's work through the code issues that are causing it to fail, then confirm if your core implementation idea is on the right track.
Code Errors to Fix
Your matrix-filling logic has several syntax and logical mistakes that are blocking proper execution:
Syntax Mix-Up: Assignment vs. Comparison
You wroteif (j=0)which is an assignment, not a condition check. In C, this will always evaluate to0(false), so your code skips thej=0block entirely. Change it toif (j == 0). Also, you forgot curly braces{}around the code blocks under yourifstatements—this means only the first line after theifis part of the block, leading to broken, unstructured logic.Empty Comparisons That Do Nothing
Lines likev[i][j]!=v[i-1][j];are just boolean checks that don't influence the value you assign. You need to filter candidate values that meet all three required conditions before picking the minimum, not just callmin()on the originalarrayindex(which never changes, so it always returns0).No Tracking of Used Values
Yourarrayindexarray stays static for every cell, so you're not excluding numbers already used in the current row or present in the column above. You need to dynamically generate a list of valid candidates for each cell.
Corrected Code Example
Here's a revised version of your matrix-filling logic that fixes these issues:
// ... (keep your input reading and first row setup code) // Fill the matrix correctly for(int i=1; i<k; i++) { int used_in_row[k] = {0}; // Track numbers already used in the current row for(int j=0; j<k; j++) { // Find the smallest valid number for this cell for(int num=0; num<k; num++) { int is_valid = 1; // Check condition 1: Not used in current row if (used_in_row[num] == 1) is_valid = 0; // Check condition 2: Not present in column j above current row for(int row=0; row<i; row++) { if (v[row][j] == num) { is_valid = 0; break; } } // Check condition 3: No fixed point (num != current row index) if (num == i) is_valid = 0; if (is_valid) { v[i][j] = num; used_in_row[num] = 1; break; // Take the smallest valid number and move to next cell } } } } // Print the matrix properly printf("\nThe matrix is:\n"); for(int i=0; i<k; i++) { printf("\n"); for(int j=0; j<k; j++) { printf("%d ", v[i][j]); } }
Verifying Your Implementation Approach
Your core idea is 100% correct! Here's why:
- By ensuring each column has unique values, you guarantee no collision with previous permutations (since collision means sharing a value at the same index, which the column uniqueness rule prevents).
- Tracking used values in each row ensures every row is a valid permutation of 0 to k-1.
- Excluding
num == iensures each row is a derangement (no fixed points). - Picking the smallest valid number for each cell ensures you generate the lex smallest possible derangement that doesn't collide with prior rows, exactly matching your requirements.
内容的提问来源于stack exchange,提问作者Dsrksidemath

