#include #include #include #include #include #include using namespace std; int N, M, B, K, NN, max_res, res[1001], s[1001][1001], tab_and[1001]; int tem[1001], e[1001]; int timer; struct statis { int n, sum; bool operator < (const statis &a) const { return (this->sum < a.sum); } }st[1001]; void Input() { int a, b; FILE*in = fopen("subsetselection.in", "r"); fscanf(in, "%i %i %i\n", &N, &M, &B); for (int i = 1; i <= N; i++) { for (int j = 1; j <= M; j++) { fscanf(in, "%i \n", &s[i][j]); } fscanf(in, "\n"); } } bool Timer(){ return clock() / (double)CLOCKS_PER_SEC > 4.8; } void MinSum() { for (int i = 1; i <= N; i++){ st[i].n = i; for (int j = 1; j <= M; j++) { st[i].sum += s[i][j]; } } sort(&st[1], &st[N + 1]); for (int i = 1; i <= N; i++) { e[i] = st[i].n; } } void Solve() { int c, cc, a, sum = 0, tsum, vsum; tab_and[1] = 1; for (int i = 2; i <= N; i++) { tab_and[i] = tab_and[i - 1] * 2; } cc = (int)pow(2, N) - 1; for (int c = 1; c <= cc; c++) { tsum = 0; for (int j = 1; j <= M; j++) { vsum = 0; for (int i = 1; i <= N; i++) { if ((c & tab_and[i]) == 0)continue; vsum += s[i][j]; } a = vsum % B; tsum += a*a; } if (tsum > sum) { sum = tsum; max_res = c; } } a = 1; for (int i = 1; i <= N; i++) { if ((max_res & tab_and[i]) > 0) { K++; res[a] = i; a++;} } } void Solve5(int NN) { MinSum(); int c, cc, a, sum = 0, tsum, vsum; tab_and[1] = 1; for (int i = 2; i <= NN; i++) { tab_and[i] = tab_and[i - 1] * 2; } cc = (int)pow(2, NN) - 1; for (int c = 1; c <= cc; c++) { tsum = 0; for (int j = 1; j <= M; j++) { vsum = 0; for (int i = 1; i <= NN; i++) { if ((c & tab_and[i]) == 0)continue; vsum += s[e[i]][j]; } a = vsum % B; tsum += a*a; } if (tsum > sum) { sum = tsum; max_res = c; } if (Timer()) break; } a = 1; for (int i = 1; i <= NN; i++) { if ((max_res & tab_and[i]) > 0) { K++; res[a] = st[i].n; a++; } } } void Solve7() { MinSum(); int c, cc, a, sum = 0, tsum, vsum, NN = 17; tab_and[1] = 1; for (int i = 2; i <= NN; i++) { tab_and[i] = tab_and[i - 1] * 2; } cc = (int)pow(2, NN) - 1; for (int c = 1; c <= cc; c++) { tsum = 0; for (int j = 1; j <= M; j++) { vsum = 0; for (int i = 1; i <= NN; i++) { if ((c & tab_and[i]) == 0)continue; vsum += s[e[i]][j]; } a = vsum % B; tsum += a*a; } if (tsum > sum) { sum = tsum; max_res = c; } if (Timer()) break; } a = 1; for (int i = 1; i <= NN; i++) { if ((max_res & tab_and[i]) > 0) { K++; res[a] = st[i].n; a++; } } } void Output() { FILE *out = fopen("subsetselection.out", "w"); fprintf(out, "%i\n", K); for (int i = 1; i <= K; i++) { fprintf(out, "%i\n", res[i]); } } int main() { Input(); if (N <= 20) { Solve(); Output(); return 0; } if (N <= 200) { Solve5(19); Output(); return 0; } Solve7(); Output(); return 0; }