標籤:style http color os io for
題目連結:uva 269 - Counting Patterns
題目大意:給出n和k,要求找出滿足的序列,要求為n元組,由-k到k組成,並且和為0。求出所有滿足的元組個數,並且對於左移,右移,水平翻轉,每個元素取相反數相同的視為一種,用字典序最大的表示,輸出按照字典序最小的輸出。
解題思路:因為表示的時候按照字典序最大的表示,一開始枚舉開頭的位置,那麼在後面的數的絕對值就不會大於該數。最後判斷一下,如果該序列不是最優的表示方法,就不是該情況。
#include <cstdio>#include <cstring>#include <cstdlib>#include <algorithm>using namespace std;const int maxn = 100005;const int maxm = 15;int s[maxn][maxm];int n, k, key, cnt, a[maxm];void put (int num[]) { printf("(%d", num[0]); for (int i = 1; i < n; i++) printf(",%d", num[i]); printf(")\n");}bool cmp (int l[], int r[]) { for (int i = 0; i < n; i++) if (l[i] != r[i]) return l[i] > r[i]; return false;}void check () { int b[maxm*2]; for (int i = 0; i < n; i++) b[i] = b[i+n] = a[i]; for (int i = 0; i < n; i++) if (b[i] == a[0] && cmp(b+i, a)) return; for (int i = 0; i < 2 * n; i++) b[i] = -b[i]; for (int i = 0; i < n; i++) if (b[i] == a[0] && cmp(b+i, a)) return; for (int i = 0; i < n; i++) swap(b[i], b[2*n-i-1]); for (int i = 0; i < n; i++) if (b[i] == a[0] && cmp(b+i, a)) return; for (int i = 0; i < 2 * n; i++) b[i] = -b[i]; for (int i = 0; i < n; i++) if (b[i] == a[0] && cmp(b+i, a)) return; memcpy(s[cnt++], a, sizeof(a));}void dfs (int d, int sum) { if (d == n) { if (sum == 0) check(); return; } if (abs(sum) > ((n - d) * a[0])) return; for (a[d] = -key; a[d] < key; a[d]++) { if (a[d-1] == key && a[d] > a[1]) return; dfs(d + 1, sum + a[d]); } if (a[d] == key && a[d-1] <= a[1]) dfs(d+1, sum+a[d]);}int main () { int cas = 0; while (scanf("%d%d", &n, &k) == 2 && n) { cnt = 1; for (a[0] = 1; a[0] <= k; a[0]++) { key = a[0]; dfs(1, key); } if (cas++) printf("\n"); printf("%d\n", cnt); for (int i = 0; i < cnt; i++) put(s[i]); } return 0;}