A.
题意就是输入n,m,代表行含n格,列含m格,让我们在这个网格里面找线段,要求线段中点是交叉点;求有几个线段。
题解;
我们可以分析知道,把每一行每一列的含有合法的线段找出来,然后找出类似2*2,4*4的正方形的所有个数*2;
全部加起来就是答案。
#include <bits/stdc++.h> using namespace std; long long sum = 0, sum1 = 0, sum2 = 0; int main() { int n, m; cin >> n >> m; for (int i = 2; i <= n; i += 2) { sum += n + 1 - i; } for (int i = 2; i <= m; i += 2) { sum1 += m + 1 - i; } sum2 += sum * (m + 1) + sum1 * (n + 1); for (int i = 1; i <= n; i++) { sum2 += sum1 * (i / 2) * 2; } cout << sum2 << endl; }
M.
题意就是给出a排列,b排列,我们的结果序列可以加ai,但是如果i>2,j>2;i^k=j,我们的结果就要减bj,求结果最大化。
我们可以用2,3,5……的的K次方来搞在每一个里面找到最大的数,然后加起来。
#include <bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1e6 + 7; long long a[maxn], b[maxn], vis[maxn] = {0}, c[maxn], d[maxn]; int pd(int x, int y) { for (ll i = x; i <= y; i *= x) { if (i == y) { return 1; } } return 0; } int main() { int n; cin >> n; for (int i = 1; i <= n; i++) { cin >> a[i]; } for (int i = 1; i <= n; i++) { cin >> b[i]; } long long sum1 = 0; ll maxn; sum1 = a[1]; for (int i = 2; i <= n; i++) { long long add = 0; maxn = 0; if (!vis[i]) { for (ll j = i; j <= n; j *= i) { c[add++] = j; vis[j] = 1; } for (int g = 0; g < (1 << add); g++) { ll add1 = 0; long long sum = 0; for (int h = 0; h < add; h++) { if (g & (1 << h)) { sum += a[c[h]]; d[add1++] = c[h]; } } for (int i = 0; i < add1; i++) { for (int j = 0; j < add1; j++) { if (d[i] < d[j] && pd(d[i], d[j])) { sum -= b[d[j]]; } } } maxn = max(maxn, sum); } } sum1 += maxn; } cout << sum1 << endl; }