牛客网OJ题解--20210308
数学考试
https://ac.nowcoder.com/acm/problem/15553
本系列记录翀翀😐痛苦的刷题日志,所有题目均来自于牛客网OJ题目,坚持刷题谈起来容易做起来难,希望我可以坚持下去,这里仍然分享一段励志文案:每个人都有梦想,然而有些人把梦想变成了现实,有些人的梦想依旧是梦想,只因为他们为梦想付出的努力程度不一样,他们坚持的时间不一样,最终才有这样的结果。
NC15553-数学考试
题目链接
https://ac.nowcoder.com/acm/problem/15553
题目描述
今天qwb要参加一个数学考试,这套试卷一共有n道题,每道题qwb能获得的分数为ai,qwb并不打算把这些题全做完,他想选总共2k道题来做,并且期望他能获得的分数尽可能的大,他准备选2个不连续的长度为k的区间, 即[L,L+1,L+2,....,L+k-1],[R,R+1,R+2,...,R+k-1](R >= L+k)。
第一行一个整数T(T<=10),代表有T组数据
接下来一行两个整数n,k,(1<=n<=200,000),(1<=k,2k <= n)
接下来一行n个整数a1,a2,...,an,(-100,000<=ai<=100,000)
输出一个整数,qwb能获得的最大分数。
测试样例
输入
2 6 3 1 1 1 1 1 1 8 2 -1 0 2 -1 -1 2 3 -1
输出
6 7
解题思路
这道题看似简单,但是时间卡的很死,暴力TLE,所以需要使用前缀和,然后统计长度时从第k为寻找即可。同时两个区间要没有交集,因此一个从l查找,一个从l+k查找即可避免。解题代码非常巧,多积累,这种前缀和的思想很重要。
解题代码
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[2000005];
int main()
{
ios::sync_with_stdio(0);
int t;
cin >> t;
while (t--)
{
int n, k;
cin >> n >> k;
for (int i = 1; i <= n; i++)
{
//前缀和,a[i]就是1~i的所有数之和
cin >> a[i], a[i] += a[i - 1];
}
ll ma = -1e18, ans = -1e18;
//从k开始找,意味着一定是长度大于等于k的数之和
for (int i = k; i + k <= n; i++)
{
//寻找第一个最大值,a[i]-a[i-k]保证了长度一定是k
ma = max(ma, a[i] - a[i - k]);
//很巧,ans刚好是找a[i+1]~a[i+k]的数之和,避免了两个区间交叉的情况出现
ans = max(ans, ma + a[i + k] - a[i]);
}
cout << ans << endl;
}
system("pause");
return 0;
} NC15172-情人节的电灯泡
题目链接
https://ac.nowcoder.com/acm/problem/15172
题目描述
情人节到了,小芳和小明手牵手,打算过一个完美的情人节,但是小刚偏偏也来了,当了一个明晃晃的电灯泡,小明很尴尬,就和小刚说,我交给你个任务,你完成了我俩就带你玩,否则你就回家吧。小刚很有当单身狗的觉悟,他坚决不想让小明过好情人节,同为单身狗的你能帮帮他吗?现在有一个n×n(1 <= n <= 1000)的格子,每一个格子都有一个电灯泡,可能是亮的,也可能是灭的(1代表亮, 0代表灭),现在有两种操作,一种是给你一个坐标,对于那个坐标上的灯泡,如果他是亮的,那么熄灭他,反之如果他是灭的,那么打开它。第二种操作是给你两个坐标,第一个坐标代表一个子矩阵的左上角,另一个坐标是右下角,请你求出当前子矩阵中有多少个灯泡是亮着的。燥起来吧!!!单身狗们!!!!
第一行两个整数,n(1 <= n <= 1000)和m(1 <= m <= 100000),分别代表正方形格子的边长和询问次数。
接下来n行,每一行有n个bool形数字(0或1),代表灯泡的状态。
接下来m行,每一行第一个数字f(1或2)代表操作的类型,如果f是1,那么接下来输入一个坐标(x, y)(1 <= x, y <= n),对于当前位置的灯泡状态进行改变,如果是2,那么接下来输入两个坐标(x1, y1)(1 <= x1, y1 <= n), (x2, y2)(1 <= x2, y2 <= n),确定子矩阵的位置,输出子矩阵中亮着的灯泡数量并换行。对于每一个2操作,输出子矩阵中亮着的灯泡数量并换行。
测试样例
输入
6 4 0 0 1 0 1 0 1 0 1 1 0 1 1 0 0 0 0 0 1 1 0 0 1 0 0 0 0 0 1 1 0 0 0 0 1 0 2 2 2 4 5 1 1 1 2 1 1 6 6 1 2 6
输出
4 14
解题思路
大水题,直接模拟即可,以后再也不摸鱼了www。
解题代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1005;
int _map[N][N];
void find(int a, int b, int c, int d)
{
int sum = 0;
for (int i = a; i <= c; i++)
{
for (int j = b; j <= d; j++)
{
if (_map[i][j])
sum++;
}
}
cout << sum << endl;
}
int main()
{
int n, m;
cin >> n >> m;
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
cin >> _map[i][j];
}
}
while (m--)
{
int index;
cin >> index;
if (index == 1)
{
int x, y;
cin >> x >> y;
_map[x][y] = !_map[x][y];
}
else
{
int a, b, c, d;
cin >> a >> b >> c >> d;
find(a, b, c, d);
}
}
system("pause");
return 0;
}
查看11道真题和解析