problem1 linkcode
首先,若是一個數字的某一位是1可是$goal$的這一位不是1,那麼這個數字是不用管它的。那麼對於剩下的數字,只須要統計在$goal$爲1的位上,這些數字對應位上也是1的數字個數。全部這樣的位取最小值便可。這些數字就是要都被刪除的。blog
problem2 linkget
首先暴力枚舉哪些行是最後迴文的行。而後對於列來講,將其對稱摺疊成$\frac{m}{2}$列,每一列能夠選擇0、一、2個,最後選出$columnCount$列。這個能夠動態規劃。string
problem3 linkhash
考慮一條線一條線添加進去。it
每次添加一條線所增長的區域等於1加上這條線與已有的線交點的個數。若是多個線交於一點那麼這個點只能算一次。io
對於一條線$y=ax+b$,只須要考慮如下這些直線:$y=a^{'}x+b^{'},0\leq a^{'}<a,0\leq b^{'}<B$table
交點爲橫座標爲$x=\frac{b^{'}-b}{a-a^{'}}=\frac{p}{q},-b\leq p<B-b,1\leq q\leq a$ast
能夠將$p$分爲三段:$-b\leq p<0,p=0,0<p<B-b$class
若是當前直線與以前的兩條線相交於一點,那麼有$\frac{p_{1}}{q_{1}}=\frac{p_{2}}{q_{2}}$,那麼只須要考慮$p_{i},q_{i}$互質的那一組便可。因爲$q$的連續性,必有一組是互質的。
令$f[a][b]=\sum_{i=1}^{a}\sum_{j=1}^{b}[Gcd(i,j)=1]$
因此答案爲$f[a][b]+1+f[a][B-b-1]$表示上面分紅的三段。
code for problem1
#include <algorithm> #include <vector> class ORSolitaire { public: int getMinimum(const std::vector<int> &numbers, int goal) { std::vector<int> b(30); for (auto x : numbers) { if ((goal & x) == x) { for (int i = 0; i < 30; ++i) { if ((x & (1 << i)) != 0) { ++b[i]; } } } } int result = -1; for (int i = 0; i < 30; ++i) { if ((goal & (1 << i)) != 0) { if (result == -1 || result > b[i]) { result = b[i]; } } } return result; } };
code for problem2
#include <string> #include <vector> class PalindromeMatrix { public: int minChange(const std::vector<std::string> &A, int rowCount, int columnCount) { int n = static_cast<int>(A.size()); int m = static_cast<int>(A[0].size()); int result = n * m; for (int mask = 0; mask < (1 << n); ++mask) { std::vector<int> rows; for (int i = 0; i < n; ++i) { if ((mask & (1 << i)) != 0) { rows.push_back(i); } } if (static_cast<int>(rows.size()) == rowCount) { result = std::min(result, Compute(rows, A, columnCount, n, m)); } } return result; } private: int Compute(const std::vector<int> &rows, const std::vector<std::string> &A, int column, int n, int m) { auto Cost = [&](int c1, int c2, int tag) { std::vector<int> visited(n); std::vector<int> row_hash(n); for (auto r : rows) { row_hash[r] = 1; } int result = 0; for (auto r : rows) { if (visited[r] == 1) { continue; } int c[2] = {0, 0}; visited[r] = 1; ++c[A[r][c1] - '0']; ++c[A[r][c2] - '0']; if (tag == 1) { ++c[A[n - 1 - r][c1] - '0']; visited[n - 1 - r] = 1; if (row_hash[n - 1 - r] == 1) { ++c[A[n - 1 - r][c2] - '0']; } } else if (tag == 2) { ++c[A[n - 1 - r][c2] - '0']; visited[n - 1 - r] = 1; if (row_hash[n - 1 - r] == 1) { ++c[A[n - 1 - r][c1] - '0']; } } else if (tag == 3) { ++c[A[n - 1 - r][c2] - '0']; ++c[A[n - 1 - r][c1] - '0']; visited[n - 1 - r] = 1; } result += std::min(c[0], c[1]); } for (int i = 0; i < n / 2; ++i) { if (visited[i] == 0) { if ((tag & 1) == 1 && A[i][c1] != A[n - 1 - i][c1]) { ++result; } if ((tag & 2) == 2 && A[i][c2] != A[n - 1 - i][c2]) { ++result; } } } return result; }; std::vector<std::vector<int>> f(m >> 1, std::vector<int>(column + 1, -1)); auto Update = [&](int i, int j, int cost) { if (j <= column && (f[i][j] == -1 || f[i][j] > cost)) { f[i][j] = cost; } }; Update(0, 0, Cost(0, m - 1, 0)); Update(0, 1, std::min(Cost(0, m - 1, 1), Cost(0, m - 1, 2))); Update(0, 2, Cost(0, m - 1, 3)); for (int i = 1; i < (m >> 1); ++i) { for (int j = 0; j <= column; ++j) { if (f[i - 1][j] == -1) { continue; } Update(i, j, f[i - 1][j] + Cost(i, m - 1 - i, 0)); Update(i, j + 1, f[i - 1][j] + std::min(Cost(i, m - 1 - i, 1), Cost(i, m - 1 - i, 2))); Update(i, j + 2, f[i - 1][j] + Cost(i, m - 1 - i, 3)); } } return f[m / 2 - 1][column]; } };
code for problem3
constexpr int kMax = 1200; int table[kMax][kMax]; class LotsOfLines { public: long long countDivisions(int A, int B) { Initialize(A, B); long long result = B + 1; for (int a = 1; a < A; ++a) { for (int b = 0; b < B; ++b) { result += 2 + table[a][b] + table[a][B - 1 - b]; } } return result; } private: void Initialize(int A, int B) { for (int i = 1; i < A; ++i) { for (int j = 1; j < B; ++j) { int t = Gcd(i, j) == 1 ? 1 : 0; table[i][j] = table[i - 1][j] + table[i][j - 1] - table[i - 1][j - 1] + t; } } } int Gcd(int x, int y) { return y == 0 ? x : Gcd(y, x % y); } };