P1147 连续自然数和
S o l u t i o n Solution Solution
简单的推式题。
若
L
,
R
L,R
L,R 满足
L
+
(
L
+
1
)
+
(
L
+
2
)
+
.
.
.
+
R
=
M
,
(
L
,
R
,
M
∈
Z
)
L+(L+1)+(L+2)+...+R=M,~~~~(L,R,M\in Z)
L+(L+1)+(L+2)+...+R=M, (L,R,M∈Z)
可得
(
L
+
R
)
×
(
R
−
L
+
1
)
2
=
M
{{(L+R)\times(R-L+1)}\over{2}}=M
2(L+R)×(R−L+1)=M
即
(
L
+
R
)
×
(
R
−
L
+
1
)
=
2
M
(L+R)\times(R-L+1)=2M
(L+R)×(R−L+1)=2M
显然
(
L
+
R
)
(L+R)
(L+R) 与
(
R
−
L
+
1
)
(R-L+1)
(R−L+1) 均为
2
M
2M
2M 的约数且的奇偶性不同
设
L
+
R
=
k
1
,
R
−
L
+
1
=
k
2
L+R=k_1,R-L+1=k_2
L+R=k1,R−L+1=k2
则
L
=
1
2
(
k
1
−
k
2
+
1
)
,
R
=
1
2
(
k
1
+
k
2
−
1
)
L={1\over2}(k_1-k_2+1),R={1\over2}(k_1+k_2-1)
L=21(k1−k2+1),R=21(k1+k2−1)
可以想到枚举
2
M
2M
2M 的约数,然后判断是否不同奇偶,直接计算
L
,
R
L,R
L,R 即可。
C o d e Code Code
时间复杂度 O ( M ) O(\sqrt {M}) O(M)。
#include <bits/stdc++.h>
using namespace std;
signed main() {
int m;
cin >> m; m *= 2;
int sq = sqrt(m);
for (int i = sq; i > 1; i--) {
if (m % i == 0) {
int x = m / i, y = i;
if ((x & 1) != (y & 1)) {
int L = (x - y + 1) / 2;
int R = (x + y - 1) / 2;
printf("%d %d\n", L, R);
}
}
}
}
P1190 [NOIP2010 普及组] 接水问题
S o l u t i o n Solution Solution
关注到数据很小,答案不会超过 ∑ w i \sum w_i ∑wi,所以直接按照题面模拟即可。
C o d e Code Code
时间复杂度 O ( a n s ) O(ans) O(ans)。
#include <bits/stdc++.h>
using namespace std;
int n, m, w[10005], ans;
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) cin >> w[i];
for (int j = m; j <= n;) {
for (int i = 0; i < m; i++) {
w[i]--;
if (w[i] == 0) w[i] = w[j++];
}
ans++;
}
for (int i = 1; i < m; i++) w[0] = max(w[0], w[i]);
cout << ans + w[0];
}
P1719 最大加权矩形
S o l u t i o n Solution Solution
枚举矩形的左上角 ( x 1 , y 1 ) (x_1,y_1) (x1,y1) 和右下角 ( x 2 , y 2 ) (x_2,y_2) (x2,y2),用二维前缀和可以做到 O ( n 2 ) O(n^2) O(n2) 预处理, O ( 1 ) O(1) O(1) 询问。
C o d e Code Code
时间复杂度 O ( n 4 ) O(n^4) O(n4)。
#include <bits/stdc++.h>
using namespace std;
int n, ans = -1e9;
int sum[125][125];
signed main() {
cin >> n;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> sum[i][j];
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
sum[i][j] += sum[i][j - 1] + sum[i - 1][j] - sum[i - 1][j - 1];
for (int x1 = 1; x1 <= n; x1++) {
for (int x2 = x1; x2 <= n; x2++) {
for (int y1 = 1; y1 <= n; y1++) {
for (int y2 = y1; y2 <= n; y2++) {
ans = max(ans, sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1]);
}
}
}
}
printf("%d", ans);
}