问题描述: 计算从某个输入n向上的所有序列的数量。 所以用户输入n;然后我创建一个数字1..n数组,然后用该属性编号序列
示例:n = 4
1 3 2 4
1 4 2 3
2 3 1 4
2 4 1 3
3 4 1 2
答案:5
我的程序有效,但出于某种原因,我有时会得到0而不是答案。
#include <stdio.h>
#include <stdlib.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
void swap(int *fir, int *sec) {
int temp = *fir;
*fir = *sec;
*sec = temp;
}
void permute(int *array, int i, int length, int *count) {
if (length == 2) {
*count = 1;
return;
}
if (length == i) {
int v = 0, flag = 1;
while (v < length) {
if (v % 2 == 0) {
if (array[v] < array[v + 1]) {
v++;
} else {
flag = 0;
return;
}
}
if (v % 2 != 0) {
if (array[v] > array[v + 1]) {
v++;
} else {
flag = 0;
return;
}
}
}
if (flag == 1) {
/*
int a;
for (a = 0; a < length; a++)
printf("%d", array[a]);
printf("\n");
*/
*count = *count + 1;
}
}
int j = i;
for (j = i; j < length; j++) {
swap(array + i, array + j);
permute(array, i + 1, length, count);
swap(array + i, array + j);
}
return;
}
int main(int argc, char **argv) {
int n;
scanf("%d", &n);
int *arr = safeMalloc(n * sizeof(int));
int i;
for (i = 0; i < n; i++) {
arr[i] = i + 1;
}
int count = 0;
permute(arr, 0, n, &count);
printf("%d\n", count);
return 0;
}
答案 0 :(得分:1)
如果你调用tab(n,k)长度为n的更新序列的数量,其中k是序列中的最后一个数字,你可以编写一个递归公式并按如下方式实现:
map[playerX-1, playerY]
答案 1 :(得分:1)
您基本上生成数组元素的所有排列并计算有效元素。
您的代码有一个小缺陷:
while (v < length) {
走得太远:您访问tab[v + 1]
,因此循环应停在v < length - 1
。按照目前的编码,它有不确定的行为。您可以进一步简单地使用代码:
length == 2
。flag
没用,因为当你清除它时总是会回来。if (v % 2 != 0)
是多余的:else
就足够了。这是一个固定和简化的版本:
#include <stdio.h>
#include <stdlib.h>
void *safeMalloc(int n) {
void *p = malloc(n);
if (p == NULL) {
printf("Error: malloc(%d) failed. Out of memory?\n", n);
exit(EXIT_FAILURE);
}
return p;
}
void swap(int *fir, int *sec) {
int temp = *fir;
*fir = *sec;
*sec = temp;
}
void permutate(int *array, int i, int length, int *count) {
if (i == length) {
for (int v = 0; v < length - 1; v++) {
if (v % 2 == 0) {
if (array[v] >= array[v + 1]) {
return;
}
} else {
if (array[v] <= array[v + 1]) {
return;
}
}
}
*count = *count + 1;
} else {
for (int j = i; j < length; j++) {
swap(array + i, array + j);
permutate(array, i + 1, length, count);
swap(array + i, array + j);
}
}
}
int main(int argc, char **argv) {
int n;
if (scanf("%d", &n) == 1 && n > 0) {
int *arr = safeMalloc(n * sizeof(int));
for (int i = 0; i < n; i++) {
arr[i] = i + 1;
}
int count = 0;
permutate(arr, 0, n, &count);
printf("%d\n", count);
}
return 0;
}
答案 2 :(得分:1)
您可以在不迭代排列的情况下解决此问题。假设您正在尝试计算f(n)。新的,高数字哪里可以去?它必须处于“向上”位置,这是一个平坦的位置。你可以在它之前有任何有效的奇数长度序列,以及它后面的任何有效序列。
假设我们正在计算f(n,k),其中最高的val位于位置k,零索引。 k均匀为零。对于奇数k,我们得到:
f(n,k)=选择(n-1,k)* f(k)* f(n - k - 1)
为了得到f(n),求和f(n,k)超过奇数k 我们必须手工计算前几个。f(0) = 1
f(1) = 1
f(2) = 1
f(3) = f(3,1) = choose(2,1) * f(1) * f(1) = 2 * 1 *1 = 2
f(4) = f(4,1) + f(4,3) = choose(3,1) * f(1) * f(2) + choose(3,3) * f(3) * f(0) = 3*1*1 + 1*2*1 = 5
f(5) = f(5,1) + f(5,3) = choose(4,1) * f(1) * f(3) + choose(4,3) * f(3) * f(1) = 4*1*2 + 4*2*1 = 16