UVa上看不到题目了,可以在UVa Live上或者VJudge上看题目。这里贴个:
Description
|
Counting Patterns |
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.
Input
The 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.
Output
The 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 Input
8 0 4 2
Sample Output
1 (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(")");
}
}
}