2014-09-11 解題區/解題區 - UVa UVa 10571 - Products contents 1. Problem2. Sample Input3. Sample Output4. Solution Problem 所有使用的數字不可重複 每一行、每一列恰好使用兩個數字 每行、每列的非零數字相乘恰好符合需求 Sample Input1234567891011121322 123 835 8 182 30 12554 6 12 20 8818 9 132 32 10102 12 30 56 90 132 182 240 306 38019 36 51 64 75 84 91 96 99 2000 Sample Output12345678910111213141516171819202122231 32 41 2 05 0 60 4 36 3 0 0 09 0 1 0 00 0 12 0 110 0 0 4 80 2 0 5 01 0 0 0 0 0 0 0 0 192 0 0 0 0 0 0 0 18 00 3 0 0 0 0 0 0 17 00 4 0 0 0 0 0 16 0 00 0 5 0 0 0 0 15 0 00 0 6 0 0 0 14 0 0 00 0 0 7 0 0 13 0 0 00 0 0 8 0 12 0 0 0 00 0 0 0 9 11 0 0 0 00 0 0 0 10 0 0 0 0 20 Solution直接每一行每一行搜索,過程中預處理所有因數分解,並且同時剪枝不合法的列。 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990#include <stdio.h> #include <vector>#include <assert.h>using namespace std;int N, X[16] = {}, Y[16] = {};int g[16][16] = {};vector<int> row[16];vector<int> f[1024];int used[1024] = {};int dfs(int idx) { if (idx == N) { for (int i = 0; i < N; i++, puts("")) { for (int j = 0; j < N; j++) { if (j) putchar(' '); printf("%3d", g[j][i]); } } return 1; } for (int p = 0; p < N; p++) { for (int q = p + 1; q < N; q++) { if (row[p].size() == 2 || row[q].size() == 2) continue; for (int i = 0; i < f[X[idx]].size(); i++) { int a, b, ok = 1; a = f[X[idx]][i]; b = X[idx]/a; if (used[a] || used[b] || a == b) continue; g[idx][p] = a, g[idx][q] = b; used[a] = used[b] = 1; row[p].push_back(a); row[q].push_back(b); if (row[p].size() == 2 && row[p][0] * row[p][1] != Y[p]) ok = 0; if (row[q].size() == 2 && row[q][0] * row[q][1] != Y[q]) ok = 0; if (Y[p]%a || Y[q]%b) ok = 0; if (ok) { if (dfs(idx + 1)) { g[idx][p] = 0, g[idx][q] = 0; row[p].pop_back(); row[q].pop_back(); used[a] = used[b] = 0; return 1; } } g[idx][p] = 0, g[idx][q] = 0; used[a] = used[b] = 0; row[p].pop_back(); row[q].pop_back(); } } } return 0;}int main() { for (int i = 1; i < 1024; i++) { for (int j = 1; j <= i; j++) { if (i%j == 0) f[i].push_back(j); } } while (scanf("%d", &N) == 1 && N) { for (int i = 0; i < N; i++) scanf("%d", &X[i]); for (int i = 0; i < N; i++) scanf("%d", &Y[i]); assert(dfs(0) == 1); puts(""); } return 0;}/*22 123 835 8 182 30 12554 6 12 20 8818 9 132 32 10102 12 30 56 90 132 182 240 306 38019 36 51 64 75 84 91 96 99 2000*/ Newer UVa 10665 - Diatribe against Pigeonholes Older UVa 1368 - DNA Consensus String