Day 3(备战实习版)

学习资料参考自 代码随想录

练习题目1
题目描述

58. 区间和(第九期模拟笔试)

给定一个整数数组 Array,请计算该数组在每个指定区间内元素的总和。

输入描述

第一行输入为整数数组 Array 的长度 n,接下来 n 行,每行一个整数,表示数组的元素。随后的输入为需要计算总和的区间下标:a,b (b > = a),直至文件结束。

输出描述

输出每个指定区间内元素的总和。

输入示例

5
1
2
3
4
5
0 1
1 3

输出示例

3
9

提示信息

数据范围:
0 < n <= 100000

解题思路

58. 区间和 | 代码随想录

暴力解法在大数据量时,查询时间会超时。

前缀和:数组p保存前缀和,在求区间和时,通过p[b]-p[a]即可实现区间求和

前缀和的思想是重复利用计算过的子数组之和,从而降低区间查询需要累加计算的次数。

#include <iostream>
#include <vector>
using namespace std;
int main() {
    int n, a, b;
    cin >> n;
    vector<int> vec(n);
    for (int i = 0; i < n; i++) cin >> vec[i];
    while (cin >> a >> b) {
        int sum = 0;
        // 累加区间 a 到 b 的和
        for (int i = a; i <= b; i++) sum += vec[i];
        cout << sum << endl;
    }
}
//知识点:1.区间和的解法:前缀和 2.ACM输入输出模式

#include<iostream>
#include<vector>
using namespace std;
int main(){
    int n,a,b;
    cin>>n;//数组长度n
    vector<int> vec(n);//创建长度为n的以int为元素的数组vec
    vector<int> p(n);//创建存放'前缀和'的数组
    
    int presum=0;
    for(int i=0;i<n;i++){
        cin>>vec[i];//从键盘输入为 vec 数组赋值
        presum+=vec[i];//累加和
        p[i]=presum;//放入'前缀和'数组
    }
    
    while(cin>>a>>b){
        int sum;
        if(a==0) sum=p[b];
        else sum=p[b]-p[a-1];
        cout<<sum<<endl;
    } 
}
练习题目2

题目描述

44. 开发商购买土地(第五期模拟笔试)

在一个城市区域内,被划分成了n * m个连续的区块,每个区块都拥有不同的权值,代表着其土地价值。目前,有两家开发公司,A 公司和 B 公司,希望购买这个城市区域的土地。

现在,需要将这个城市区域的所有区块分配给 A 公司和 B 公司。

然而,由于城市规划的限制,只允许将区域按横向或纵向划分成两个子区域,而且每个子区域都必须包含一个或多个区块。 为了确保公平竞争,你需要找到一种分配方式,使得 A 公司和 B 公司各自的子区域内的土地总价值之差最小。

注意:区块不可再分。

输入描述

第一行输入两个正整数,代表 n 和 m。

接下来的 n 行,每行输出 m 个正整数。

输出描述

请输出一个整数,代表两个子区域内土地总价值之间的最小差距。

输入示例

3 3
1 2 3
2 1 3
1 2 3

输出示例

0

提示信息

如果将区域按照如下方式划分:

1 2 | 3
2 1 | 3
1 2 | 3

两个子区域内土地总价值之间的最小差距可以达到 0。

数据范围:

1 <= n, m <= 100;
n 和 m 不同时为 1。

解题思路

解析:44. 开发商购买土地 | 代码随想录

//开发商购买土地
//暴力解法

#include<iostream>
#include<vector>
#include <climits>//这是个啥不知道

using namespace std;

int main(){
    int n,m;

    cin>>n>>m;//!!!!从键盘输入n,m,对ACM输入输出还是不熟悉

    vector<vector<int>> vec(n,vector<int>(m,0));//二维数组的定义:n行,每一行都是一个长度为n的一维数组

    //输入数组元素的同时,统计sum
    int sum=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>vec[i][j];
            sum+=vec[i][j];//数组总和
        }
    }

    //行切分
    int result=INT_MAX;//
    int count=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            count+=vec[i][j];//计算第i行的总和

            if(j==m-1){//统计到最后一列进行记录
                result=min(result,abs(sum-count-count));//count:区域a,sum-count:区域b,两个区域的差值
            }

        }
    }

    //列切分
    count=0;
    for(int j=0;j<m;j++){
        for(int i=0;i<n;i++){
            count+=vec[i][j];//计算第j列的总和
            
            if(i==n-1){
                result=min(result,abs(sum-count-count));
            }
        }
    }

    cout<<result<<endl;

}
//开发商购买土地
//前缀和-需要两个额外的一维数组保存行/列切分的前缀和

//为啥一直输出6啊....
//复制粘贴的时候把变量抄错了...,神经啊

#include<iostream>
#include<vector>
#include <climits>//这是个啥不知道

using namespace std;

int main(){
    int n,m;
    cin>>n>>m;//!!!!从键盘输入n,m,对ACM输入输出还是不熟悉
    vector<vector<int>> vec(n,vector<int>(m,0));//二维数组的定义:n行,每一行都是一个长度为n的一维数组

    //输入数组元素的同时,统计sum
    int sum=0;
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            cin>>vec[i][j];
            sum+=vec[i][j];//数组总和
        }
    }
     //行切分,前缀和
    vector<int> hori(n,0);
    for(int i=0;i<n;i++){
        for(int j=0;j<m;j++){
            hori[i]+=vec[i][j];//注:循环里hori[i]+=vec[i][j]可直接加和,无需count变量
            }

        }
    //列切分,前缀和
    vector<int> verti(m,0);
    for(int j=0;j<m;j++){
        for(int i=0;i<n;i++){
           verti[j]+=vec[i][j];
            }
        }

    //行
    int result=INT_MAX;
    int horiCut=0;
    for(int i=0;i<n;i++)
    {
        horiCut+=hori[i];//+=写成=+了...
        result=min(result,abs(sum-horiCut-horiCut));

    }
    //列
    int vertiCut=0;
    for(int j=0;j<m;j++)
    {
        vertiCut+=verti[j];//复制粘贴的时候把变量抄错了...
        result=min(result,abs(sum-vertiCut-vertiCut));

    }
     cout<<result<<endl;

}

学习总结

学习内容:

  1. 前缀和的思想
  2. 二维数组的vector定义
  3. 二维数组的遍历

存在问题:

  1. 对于ACM的输入输出模式不熟悉
  2. 写代码的不良习惯,功能重复的代码段复制粘贴时,变量未完全修改
  3. 程序出现问题不会打断点调试,只会 cout 调试-_-||

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值