牛客网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;
}
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务