bool subsetSum(int *arr, int X, int i) { if ( i == 0 && arr[i] == X) return true; if ( i == 0 && arr[i] != X) return false; else { return subsetSum(arr,X-arr[i],i-1) || subsetSum(arr,X,i-1); } }
int main(){ int x = 0, y = 0, k = 1, i = 0, j = 0; while(1){ scanf("%d %d %d", &x, &y, &n); if(!x && !y && !n) break; t = 0; for(i = 1; i <= n; i++){ scanf("%d", &v[i]); t += v[i]; } t = (x + y + t); if(t % 2 != 0){ printf("Teste %d\nN\n\n", k++); continue; } t = (t / 2) - x; if(subsetSum()) printf("Teste %d\nS\n\n", k++); else printf("Teste %d\nN\n\n", k++); } return 0; }
int findTargetSumWays(vector<int>& nums, int S) { // sum(P) - sum(N) = S // <=> // 2 * sum(P) = S + sum(nums) int sum = accumulate(nums.begin(), nums.end(), 0); if (sum < S || (S + sum) % 2) { return 0; } return subsetSum(nums, (S + sum) / 2); }
int main (int argc, char *argv[]) { // read the data from a file if (argc < 2) { printf("Need input file name\n"); return EXIT_FAILURE; } FILE * fptr = fopen(argv[1], "r"); if (fptr == NULL) { printf("fopen fail\n"); return EXIT_FAILURE; } int numInt = countInteger(fptr); // go back to the beginning of the file fseek (fptr, 0, SEEK_SET); int kval; // the value equal to the sum if (fscanf(fptr, "%d", & kval) != 1) { printf("fscanf error\n"); fclose(fptr); return EXIT_FAILURE; } numInt --; // kval is not part of the set int * setA = malloc(sizeof(int) * numInt); int ind = 0; for (ind = 0; ind < numInt; ind ++) { int aval; if (fscanf(fptr, "%d", & aval) != 1) { printf("fscanf error\n"); fclose(fptr); return EXIT_FAILURE; } setA[ind] = aval; } fclose (fptr); if (isValidSet(setA, numInt) == 1) { printf("There are %d subsets whose sums are %d\n", subsetSum(setA, numInt, kval), kval); } else { printf("Invalid set\n"); } free(setA); return EXIT_SUCCESS; }
void generateSubsetSums(const unsigned target_sum, const std::vector<IntList> &possibles, std::vector<IntList> &subsets) { IntList tuple; subsetSum(possibles, possibles.size(), tuple, 0, subsets, target_sum, 0); }
// Given a list of lists of possible cage values: // [[1,2,3], [3,4,5]] // Recursively generates tuples of combinations from each of the lists as // follows: // [1,3] // [1,4] // [1,5] // [2,3] // [2,4] // ... etc // Each of these is checked against the target sum, and pushed into a result // vector if they match. // Note: The algorithm assumes that the list of possibles/candidates are // ordered. This allows it to bail out early if it detects there's no point // going further. static void subsetSum(const std::vector<IntList> &possible_lists, const std::size_t p_size, IntList &tuple, unsigned tuple_sum, std::vector<IntList> &subsets, const unsigned target_sum, unsigned list_idx) { for (unsigned p = list_idx; p < p_size; ++p) { for (auto &poss : possible_lists[p]) { // Optimization for small target sums: if the candidate is bigger than // the target itself then it can't be valid, neither can any candidate // after it (ordered). if (target_sum < static_cast<unsigned>(poss)) { break; } // Can't repeat a value inside a cage if (std::find(tuple.begin(), tuple.end(), poss) != tuple.end()) { continue; } // Pre-calculate the new tuple values to avoid spurious // insertions/deletions to the vector. const auto new_tuple_sum = tuple_sum + poss; const auto new_tuple_size = tuple.size() + 1; // If we've added too much then we can bail out (ordered). if (new_tuple_sum > target_sum) { break; } // If there are fewer spots left in the tuple than there are options for // the sum to reach the target, bail. // TODO: This could be more sophisticated (can't have more than one 1, so // it's more like the N-1 sum that it should be greater than. if ((p_size - new_tuple_size) > (target_sum - new_tuple_sum)) { break; } if (new_tuple_size == p_size) { // If we've reached our target size then we can stop searching other // possiblities from this list (ordered). if (new_tuple_sum == target_sum) { tuple.push_back(poss); subsets.push_back(tuple); tuple.pop_back(); break; } // Else, move on to the next candidate in the list. continue; } tuple_sum += poss; tuple.push_back(poss); subsetSum(possible_lists, p_size, tuple, tuple_sum, subsets, target_sum, p + 1); tuple.pop_back(); tuple_sum -= poss; } } }
int main(int argc,char *argv[]) { int arr[] = {1,4,9,2,3}; std::cout << subsetSum(arr,20,4); }
/* This is the main funtion provided to handle the file I/O and program output * Please do not modify this function. All neccessary inputs are provided through * the interface subsetSum, please implement that funtion. */ int main(int argc, char **argv) { // Check arguments if (argc < 4) { //printf("Usage: pa13 input output <number of threads>\n"); printf("Usage: %s <input_set> <input_num> <output> <number of threads>\n", argv[0]); return EXIT_FAILURE; } FILE * fpset = fopen(argv[1], "r"); FILE * fpnum = fopen(argv[2], "r"); FILE * fptr = fopen(argv[3], "w"); // check if file exist and can be read if (fpset == NULL) { fprintf(stderr, "Error opening file %s\n", argv[1]); return EXIT_FAILURE; } if (fpnum == NULL) { fprintf(stderr, "Error opening file %s\n", argv[2]); return EXIT_FAILURE; } if (fptr == NULL) { return EXIT_FAILURE; } int maxThread = (int) strtol(argv[4], NULL, 10); int numThread; int * intset, length, targetSumValue, tmp, cnt; int bfsize = INIT_SET_SIZE; intset = (int*) malloc(sizeof(int) * bfsize); cnt = 0, tmp = 0; // read set data from formated file input while ((tmp = fscanf(fpset, "%d\n", intset+cnt)) != EOF) { if (tmp <= 0) { fprintf(stderr, "Wrong input format in file %s.\n", argv[1]); return EXIT_FAILURE; } cnt += tmp; // resize array if actual number of elements is founded to be // larger than initial size if (cnt > bfsize) { bfsize += bfsize; int * nset = (int*) realloc(intset, sizeof(int) * bfsize); if (nset == 0) { fprintf(stderr, "Error allocating memory.\n"); return EXIT_FAILURE; } intset = nset; } } length = cnt; // read N from second file tmp = fscanf(fpnum, "%d\n", &targetSumValue); if (tmp <= 0) { fprintf(stderr, "Wrong input format in file %s.\n", argv[2]); return EXIT_FAILURE; } fclose(fpset); fclose(fpnum); long result = 0; for (numThread = 1; numThread <= maxThread; numThread ++) { struct timeval Time1; struct timeval Time2; gettimeofday(& Time1, NULL); //result = subsetSum(intset, length, targetSumValue, 1); result = subsetSum(intset, length, targetSumValue, numThread); gettimeofday(& Time2, NULL); printf("%d thread(s), run time: %8.4f\n", numThread, timeDiff(Time1, Time2)); } free (intset); // Write result fprintf(fptr, "%ld", result); fclose (fptr); return EXIT_SUCCESS; }