UVa上看不到題目了,可以在UVa Live上或者VJudge上看題目。這裏貼個:
Description
Let n and k be numbers with n > 0 and . A configuration of the n-k-puzzle is an n-tuple with elements in the range such that their sum is zero. Configurations are considered equivalent when they can be obtained from each other by (a) cyclic permutation of the tuple over one or more positions, (b) reversal of the tuple, (c) sign reversal of all elements, or (d) combinations of (a), (b), and (c). Equivalence classes are called patterns. For instance, (0, 1, 1, -2) is a configuration of the 4-2-puzzle. Some equivalent configurations are: (a) (1, -2, 0, 1), (b) (-2, 1, 1, 0), (c) (0, -1, -1, 2), and (d) (-1, -1, 0, 2). Below is given a list of (the lexicographically largest) representatives of the 14 patterns of the 4-2-puzzle. Your program computes the number of patterns for a sequence of n-k-puzzles. And output the list of patterns (represented by the largest one in the patterns), from lower order to higher one. InputThe input consists of a sequence of pairs of integers n and k, which are separated by a single space. Each pair appears on a single line. The input is terminated by an end-of-file. The value for n + k is at most 12. Make sure that your algorithm is fantastic enough. OutputThe output contains a sequence of blocks, the fisrt line contain a single integer(x), representing the number of patterns for the corresponding n-k-puzzles in the input, and follow x lines, each one contain one pattern(from lower order to higher one). Print one blank line between two consecutive blocks. No blank line should appear at the end of the output. Sample Input8 0 4 2 Sample Output1 (0,0,0,0,0,0,0,0) 14 (0,0,0,0) (1,-1,1,-1) (1,0,-1,0) (1,0,0,-1) (1,1,-1,-1) (2,-2,2,-2) (2,-1,0,-1) (2,-1,1,-2) (2,0,-2,0) (2,0,-1,-1) (2,0,0,-2) (2,1,-2,-1) (2,1,-1,-2) (2,2,-2,-2) |
剛開始的想法是:先構造出所有和爲0的無序的n個數,根據這個來構造出所有可能的排列。不過TLE了。
參考了神牛們的解題報告,模仿之……其思路是按照字典序構造出和爲0的排列,檢查對於所有可能的變換操作,該排列是否是最優的。是的話就記錄下來。最後打印。簡單暴力,但是很有效。代碼如下:
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <queue>
#include <vector>
#include <map>
#include <set>
#include <string>
#include <iomanip>
using namespace std;
#define ff(i, n) for(int i=0;i<(n);i++)
#define fff(i, n, m) for(int i=(n);i<=(m);i++)
#define dff(i, n, m) for(int i=(n);i>=(m);i--)
#define bit(n) (1LL<<(n))
typedef long long LL;
typedef unsigned long long ULL;
void work();
int main()
{
#ifdef ACM
// freopen("in.txt", "r", stdin);
#endif // ACM
work();
}
/***************************************************/
const int maxn = 101010;
int cnt;
int res[maxn][20];
int a[20], b[40];
int n, k;
bool bigger(int * a, int * b)
{
ff(i, n) if(a[i] != b[i])
return a[i] > b[i];
return false;
}
void check()
{
ff(i, n)
b[i] = b[i+n] = a[i];
ff(i, n) if(b[i] == a[0])
if(bigger(b+i, a)) return;
reverse(b, b+2*n);
ff(i, n) if(b[i] == a[0])
if(bigger(b+i, a)) return;
ff(i, n)
b[i] = b[i+n] = -a[i];
ff(i, n) if(b[i] == a[0])
if(bigger(b+i, a)) return;
reverse(b, b+2*n);
ff(i, n) if(b[i] == a[0])
if(bigger(b+i, a)) return;
memcpy(res[cnt++], a, sizeof(a));
}
void dfs(int pos, int sum)
{
if(pos == n)
{
if(sum == 0)
check();
return;
}
if(abs(sum) > (n-pos)*a[0]) return;
for(a[pos] = -a[0]; a[pos] <= a[0]; a[pos]++)
{
if(a[pos-1] == a[0] && a[pos] > a[1]) return;
dfs(pos+1, sum + a[pos]);
}
}
void work()
{
int first = false;
while(scanf("%d%d", &n, &k) == 2)
{
cnt = 1;
for(a[0] = 1; a[0] <= k; a[0]++)
dfs(1, a[0]);
if(first) puts("");
first = true;
printf("%d\n", cnt);
ff(i, cnt)
{
printf("(%d", res[i][0]);
fff(j, 1, n-1) printf(",%d", res[i][j]);
puts(")");
}
}
}