// SubsetSelection.cpp : This file contains the 'main' function. Program execution begins and ends there. // #define _CRT_SECURE_NO_WARNINGS #include #include using namespace std::chrono; steady_clock::time_point end = steady_clock::now() + milliseconds(4950); bool not_expired() { return steady_clock::now() < end; } int N, M, B; unsigned char A[1000][1000], T[1000], T1[1000][1000]; int I[1000]; int MI[1000]; int maxSum = -1, maxLevel = 0; void iterate(int level, int numLevels) { if (level >= 0) { for (I[level] = level; I[level] < I[level + 1] && not_expired(); I[level]++) { iterate(level - 1, numLevels); } } else { int total = 0; for (int i = 0; i < M; i++) { int sum = 0; for (int j = 0; j < numLevels; j++) { sum += A[I[j]][i]; if (sum >= B) sum -= B; } total += sum * sum; } if (maxSum < total) { maxSum = total; maxLevel = numLevels; for (int j = 0; j < numLevels; j++) MI[j] = I[j]; } } } int main() { FILE* fin = fopen("subsetselection.in", "rt"); fscanf(fin, "%d %d %d", &N, &M, &B); for (int i = 0; i < N; i++) { int sum = 0; for (int j = 0; j < M; j++) { int v; fscanf(fin, "%d", &v); A[i][j] = (unsigned char)v; sum += v * v; } // check single sets if (maxSum < sum) { maxSum = sum; MI[0] = i; maxLevel = 1; } } fclose(fin); // check sum of all sets int total = 0; for (int i = 0; i < M && not_expired(); i++) { int sum = 0; for (int j = 0; j < N; j++) { sum += A[j][i]; if (sum >= B) sum -= B; } T[i] = sum; total += sum * sum; } if (maxSum < total) { maxSum = total; maxLevel = N; for (int i = 0; i < N; i++) MI[i] = i; } // check two sets for (int i = 1; i < N && not_expired(); i++) { for (int j = 0; j < i; j++) { int sum = 0; for (int k = 0; k < M; k++) { int sij = A[i][k] + A[j][k]; if (sij >= B) sij -= B; sum += sij * sij; } //printf("s(%d,%d)=%d\n", i, j, sum); if (maxSum < sum) { maxSum = sum; MI[0] = i; MI[1] = j; maxLevel = 2; } } } for (int i = 0; i < N && not_expired(); i++) { // check sum of all sets int total = 0; for (int j = 0; j < M && not_expired(); j++) { int sum = T[j] - A[i][j]; if (sum < 0) sum += B; T1[i][j] = sum; total += sum * sum; } if (maxSum < total) { maxSum = total; maxLevel = N - 1; for (int k = 0, j = 0; k < N; k++) { if (i == k) continue; MI[j++] = k; } } } for (int i = 0; i < N - 1 && not_expired(); i++) { for (int k = i + 1; k < N && not_expired(); k++) { // check sum of all sets int total = 0; for (int j = 0; j < M && not_expired(); j++) { int sum = T1[i][j] - A[k][j]; if (sum < 0) sum += B; total += sum * sum; } if (maxSum < total) { maxSum = total; maxLevel = N - 2; for (int l = 0, j = 0; l < N; l++) { if (i == l || k == l) continue; MI[j++] = l; } } } } for (int i = 3; i <= N - 3 && not_expired(); i++) { I[i] = N; iterate(i - 1, i); } //// check all possible combinations until time expires //for (int i = 3, j = N - 2; i <= j && not_expired(); i++, j--) { // I[i] = N; // iterate(i - 1, i); // if (i < j) // { // I[j] = N; // iterate(j - 1, j); // } //} FILE* fout = fopen("subsetselection.out", "wt"); fprintf(fout, "%d\n", maxLevel); for(int i = 0; i < maxLevel; i++) fprintf(fout, "%d\n", MI[i] + 1); fclose(fout); }