#include #include #include int *genarray ( int n ) { int *A, i, S; A = (int *)malloc((n+1) * sizeof(int)); S = 0; printf("The input array:\n"); for (i=1; i<=n; ++i) { A[i] = 1 + rand() % 99; printf("%-2d ", A[i]); if (i % 20 == 0) printf("\n"); S += A[i]; } if (i % 20 != 1) printf("\n"); // A[0] = 1 + rand() % S; // A[0] = (S/2) + (rand() % (S/2)); A[0] = (2*S/3) + (rand() % (S/3)); if ((A[0] & 1) != (S & 1)) --A[0]; if (rand() & 1) A[0] = -A[0]; printf("S = %d\n", S); printf("T = %d\n", A[0]); return A; } void realizable ( int A[], int n, int T ) { int S, s, i, j; char **P; /* P[i][j] stores 0 if unrealizable, or +/- if realizable */ S = 0; for (i=1; i<=n; ++i) S += A[i]; P = (char **)malloc((n+1) * sizeof(char *)); for (i=0; i<=n; ++i) { P[i] = (char *)malloc((2*S+1) * sizeof(char)); for (j=-S; j<=S; ++j) P[i][j+S] = '\0'; } P[0][S] = '.'; s = 0; for (i=1; i<=n; ++i) { s += A[i]; for (j=-s; j<=s; ++j) { if ((j-A[i] >= -S) && (P[i-1][j-A[i]+S])) P[i][j+S] = '+'; else if ((j+A[i] <= S) && (P[i-1][j+A[i]+S])) P[i][j+S] = '-'; } } if (P[n][T+S]) printf(" The value %d is realizable\n", T); else printf(" The value %d is not realizable\n", T); for (i=0; i<=n; ++i) free(P[i]); free(P); } /* sol[] stores a sequence of n + and - signs to indicate the choice of the signs of the array elements. */ void printsol ( int A[], int n, char *sol ) { int S, i; S = 0; for (i=1; i<=n; ++i) { printf("%c%d", sol[i], A[i]); if (sol[i] == '+') S += A[i]; else if (sol[i] == '-') S -= A[i]; else fprintf(stderr, "*** Error: operator %d is %d\n", i, (int)sol[i]); } printf(" = %d\n", S); } void showone ( int A[], int n, int T ) { int S, s, i, j; char **P, *sol; /* P[i][j] stores 0 if unrealizable, or +/- if realizable */ S = 0; for (i=1; i<=n; ++i) S += A[i]; P = (char **)malloc((n+1) * sizeof(char *)); for (i=0; i<=n; ++i) { P[i] = (char *)malloc((2*S+1) * sizeof(char)); for (j=-S; j<=S; ++j) P[i][j+S] = '\0'; } P[0][S] = '.'; s = 0; for (i=1; i<=n; ++i) { s += A[i]; for (j=-s; j<=s; ++j) { if ((j-A[i] >= -S) && (P[i-1][j-A[i]+S])) P[i][j+S] = '+'; else if ((j+A[i] <= S) && (P[i-1][j+A[i]+S])) P[i][j+S] = '-'; } } if (P[n][T+S]) { sol = (char *)malloc((n+1) * sizeof(char)); j = T; i = n; while (i > 0) { sol[i] = P[i][j+S]; if (sol[i] == '+') j -= A[i]; else j += A[i]; --i; } printf(" Solution: "); printsol(A,n,sol); free(sol); } else printf(" The value %d is not realizable\n", T); for (i=0; i<=n; ++i) free(P[i]); free(P); } /* Generate all possible solution vectors recursively */ void gensol ( int **P, int **Q, int *A, char **sol, int i, int j, int S) { int npos, nneg, k; if (i <= 0) return; npos = P[i][j+S]; nneg = Q[i][j+S]; for (k=0; k= -S) P[i][j+S] = P[i-1][j-A[i]+S] + Q[i-1][j-A[i]+S]; if (j+A[i] <= S) Q[i][j+S] = P[i-1][j+A[i]+S] + Q[i-1][j+A[i]+S]; } } nsol = P[n][T+S] + Q[n][T+S]; printf(" Number of solutions = %d\n", nsol); if (nsol) { /* Allocate memory for n solution vectors */ sol = (char **)malloc(nsol * sizeof(char *)); for (i=0; i 1) n = atoi(argv[1]); else scanf("%d", &n); printf("n = %d\n", n); A = genarray(n); T = A[0]; printf("\n+++ Part 1: Realizability check\n"); realizable(A,n,T); printf("\n+++ Part 2: One solution\n"); showone(A,n,T); printf("\n+++ Part 3: All solutions\n"); showall(A,n,T); exit(0); }