A
第一题明显统计,注意0和long long(我WA,RE好几次)
/* * Problem: A. Matrix * Author: Shun Yao */ #include <string.h> #include <stdlib.h> #include <limits.h> #include <assert.h> #include <stdio.h> #include <ctype.h> #include <math.h> #include <time.h> #include <map> #include <set> #include <list> #include <stack> #include <queue> #include <deque> #include <string> #include <vector> #include <bitset> #include <utility> #include <iomanip> #include <numeric> #include <sstream> #include <iostream> #include <algorithm> #include <functional> //using namespace std; int a, n, b[4444], c[44444]; char s[4444]; int main(/*int argc, char **argv*/) { int i, j, x; long long ans; scanf("%d", &a); scanf(" %s", s + 1); n = strlen(s + 1); for (i = 1; i <= n; ++i) b[i] = s[i] - '0'; memset(c, 0, sizeof c); ans = 0; for (i = 1; i <= n; ++i) { x = 0; for (j = i; j <= n; ++j) { x += b[j]; ++c[x]; } } if (a) { for (i = 1; i <= 40000 && i * i <= a; ++i) if (a % i == 0 && a / i <= 40000) ans += static_cast<long long>(c[i]) * c[a / i] * (i * i == a ? 1 : 2); } else ans = static_cast<long long>(c[0]) * (n * (n + 1) - c[0]); printf("%I64d", ans); fclose(stdin); fclose(stdout); return 0; }
B
用背包算出每个价值是否出现过,然后贪心即可。
/* * Problem: B. Free Market * Author: Shun Yao */ #include <string.h> #include <stdlib.h> #include <limits.h> #include <assert.h> #include <stdio.h> #include <ctype.h> #include <math.h> #include <time.h> #include <map> #include <set> #include <list> #include <stack> #include <queue> #include <deque> #include <string> #include <vector> #include <bitset> #include <utility> #include <iomanip> #include <numeric> #include <sstream> #include <iostream> #include <algorithm> #include <functional> //using namespace std; int n, d, c[55], f[500010]; int main(/*int argc, char **argv*/) { int i, j, sum, ans1, ans2; scanf("%d%d", &n, &d); sum = 0; for (i = 1; i <= n; ++i) { scanf("%d", c + i); sum += c[i]; } memset(f, 0, sizeof f); f[0] = 1; for (i = 1; i <= n; ++i) for (j = sum; j >= c[i]; --j) f[j] |= f[j - c[i]]; ans1 = 0; ans2 = 0; while (ans1 < sum) { for (j = ans1 + d <= sum ? ans1 + d : sum; j > ans1; --j) if (f[j]) break; if (j <= ans1) break; ans1 = j; ++ans2; } printf("%d %d", ans1, ans2); fclose(stdin); fclose(stdout); return 0; }
C
不懂证明,求解释。。。
D
做法是随机算法(没有想到啊。)
/* * Problem: D. Ghd * Author: Shun Yao */ #include <string.h> #include <stdlib.h> #include <limits.h> #include <assert.h> #include <stdio.h> #include <ctype.h> #include <math.h> #include <time.h> #include <map> #include <set> #include <list> #include <stack> #include <queue> #include <deque> #include <string> #include <vector> #include <bitset> #include <utility> #include <iomanip> #include <numeric> #include <sstream> #include <iostream> #include <algorithm> #include <functional> //using namespace std; const int MAXN = 1000010; int n; long long a[MAXN], ans; std::vector<long long> e, v; long long gcd(long long a, long long b) { return !b ? a : gcd(b, a % b); } int main(/*int argc, char **argv*/) { int i, j, x; // freopen("D.in", "r", stdin); // freopen("D.out", "w", stdout); scanf("%d", &n); for (i = 1; i <= n; ++i) scanf("%I64d", a + i); srand((unsigned)time(0)); ans = 0; while (clock() < 3000L) { x = static_cast<long long>(rand()) * rand() % n + 1; e.clear(); v.clear(); for (i = 1; static_cast<long long>(i) * i <= a[x]; ++i) if (a[x] % i == 0) { e.push_back(i); if (static_cast<long long>(i) * i != a[x]) e.push_back(a[x] / i); } std::sort(e.begin(), e.end()); v.resize(e.size(), 0); for (i = 1; i <= n; ++i) ++v[std::lower_bound(e.begin(), e.end(), gcd(a[x], a[i])) - e.begin()]; for (i = 0; i < static_cast<int>(e.size()); ++i) { for (j = i + 1; j < static_cast<int>(e.size()); ++j) if (e[j] % e[i] == 0) v[i] += v[j]; if (v[i] + v[i] >= n) ans = std::max(ans, e[i]); } } printf("%I64d", ans); fclose(stdin); fclose(stdout); return 0; }
E
二维分治。
/* * Problem: E. Empty Rectangles * Author: Shun Yao */ #include <string.h> #include <stdlib.h> #include <limits.h> #include <assert.h> #include <stdio.h> #include <ctype.h> #include <math.h> #include <time.h> #include <map> #include <set> #include <list> #include <stack> #include <queue> #include <deque> #include <string> #include <vector> #include <bitset> #include <utility> #include <iomanip> #include <numeric> #include <sstream> #include <iostream> #include <algorithm> #include <functional> //using namespace std; int n, m, k; char s[2505][2505]; long long a[2505][2505]; inline long long sum(int r1, int c1, int r2, int c2) { return a[r2][c2] - a[r1 - 1][c2] - a[r2][c1 - 1] + a[r1 - 1][c1 - 1]; } long long go(int r1, int c1, int r2, int c2) { if (r1 == r2 && c1 == c2) return sum(r1, c1, r2, c2) == k; if (r2 - r1 > c2 - c1) { long long cnt = 0; int m = (r1 + r2) >> 1; int up[k + 1], dw[k + 1]; for (int i = c1; i <= c2; i++) { for (int x = 0; x <= k; x++)up[x] = m - r1 + 1, dw[x] = r2 - m; for (int j = i; j <= c2; j++) { for (int x = 0; x <= k; x++) { while (up[x] && sum(m - up[x] + 1, i, m, j) > x) --up[x]; while (dw[x] && sum(m + 1, i, m + dw[x], j) > x) --dw[x]; } for (int x = 0; x <= k; x++) { cnt += (long long)(up[x] - (x ? up[x - 1] : 0)) * (dw[k - x] - (k - x ? dw[k - x - 1] : 0)); } } } return cnt + go(r1, c1, m, c2) + go(m + 1, c1, r2, c2); } else { long long cnt = 0; int m = (c1 + c2) >> 1; int up[k + 1], dw[k + 1]; for (int i = r1; i <= r2; i++) { for (int x = 0; x <= k; x++)up[x] = m - c1 + 1, dw[x] = c2 - m; for (int j = i; j <= r2; j++) { for (int x = 0; x <= k; x++) { while (up[x] && sum(i, m - up[x] + 1, j, m) > x)up[x]--; while (dw[x] && sum(i, m + 1, j, m + dw[x]) > x)dw[x]--; } for (int x = 0; x <= k; x++) { cnt += (long long)(up[x] - (x ? up[x - 1] : 0)) * (dw[k - x] - (k - x ? dw[k - x - 1] : 0)); } } } return cnt + go(r1, c1, r2, m) + go(r1, m + 1, r2, c2); } } int main() { freopen("E.in", "r", stdin); freopen("E.out", "w", stdout); scanf("%d%d%d", &n, &m, &k); for (int i = 1; i <= n; i++)scanf("%s", &s[i][1]); for (int i = 1; i <= n; i++) { for (int j = 1; j <= m; j++) { a[i][j] = a[i - 1][j] + a[i][j - 1] - a[i - 1][j - 1] + s[i][j] - '0'; } } printf("%I64d", go(1, 1, n, m)); fclose(stdin); fclose(stdout); return 0; }