2021BFU暑期集训Day2——前缀和与差分

今天没能听上19级优秀集训队员的课,只能做题

A-Array and prefix sum

输入一个长度为n(1 <= n <= 100000)数组ai(0<=ai<=1000),输出他的前缀和。

前缀和中的第i项,表示原数组中的前i项的和。

Input
第一行一个整数n,表示数字长度 接下来n行,每行一个整数ai,表示数组的内容。

Output
输出第一行为数组长度n 接下来n行为前缀和的结果。

Sample Input
3
1
2
3

Sample Output
3
1
3
6

思路:基本的前缀和,不过结果要输出一次n,这一点容易忽略

#include<bits/stdc++.h>
using namespace std;
#define int long long int 
int a[100010],sum[100010];

signed main() {
	int n;
	cin>>n;
	sum[0]=0;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum[i]=sum[i-1]+a[i];
	}
	cout<<n<<endl;
	for(int i=1;i<=n;i++){
		cout<<sum[i]<<endl;
	}
}

B-Bomb

一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标。现在地图上有n(N<=10000)个目标,用整数Xi,Yi(其值在[0,5000])表示目标在地图上的位置,每个目标都有一个价值。激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆破范围,即那个边长为R的正方形的边必须和x,y轴平行。若目标位于爆破正方形的边上,该目标将不会被摧毁。

输入格式
输入文件的第一行为正整数n和正整数R,接下来的n行每行有3个正整数,分别表示xi,yi,vi

输出格式
输出文件仅有一个正整数,表示一颗炸弹最多能炸掉地图上总价值为多少的目标(结果不会超过32767)。

Sample Input
2 1
0 0 1
1 1 1

Sample Output
1

思路:一定要读明白题啊!前两个是xy坐标对应位置,后面跟着这个位置的值,这意味在5000*5000的地图上大部分点都是0,我们在对n个点赋值后求对应前缀和数组,再遍历一遍就行。

细节问题:在赋值的时候从(1,1)开始,即a[x+1][y+1]=z,遍历数组的时候才能从i=1开始

#include<bits/stdc++.h>
#define N 5001
using namespace std;

int a[5010][5010],n,r,ans;
int main() {
	std::ios::sync_with_stdio(false);//cin->scanf,更快
	cin>>n>>r;
	for(int i = 1; i <= n; i ++) { //定点赋值
		int x,y,z;
		cin>>x>>y>>z;
		a[x + 1][y + 1] += z;
	}

	for(int i = 1; i <= N; i ++)//行求前缀和
		for(int j = 1; j <= N; j ++)
			a[i][j] += a[i - 1][j];

	for(int i = 1; i <= N; i ++)//列求前缀和,加上之前的行求前缀和,此步求完了前缀和
		for(int j = 1; j <= N; j ++)
			a[i][j] += a[i][j - 1];

	for(int i = r; i <= N; i ++)//从(r,r)开始遍历,求最值
		for(int j = r; j <= N; j ++)
			ans = max(ans, a[i][j] + a[i - r][j - r] - a[i][j - r] - a[i - r][j]);
	cout<<ans;
}

C-Tallest Cow

FJ’s N (1 ≤ N ≤ 10,000) cows conveniently indexed 1…N are standing in a line. Each cow has a positive integer height (which is a bit of secret). You are told only the height H (1 ≤ H ≤ 1,000,000) of the tallest cow along with the index I of that cow.

FJ has made a list of R (0 ≤ R ≤ 10,000) lines of the form “cow 17 sees cow 34”. This means that cow 34 is at least as tall as cow 17, and that every cow between 17 and 34 has a height that is strictly smaller than that of cow 17.

For each cow from 1…N, determine its maximum possible height, such that all of the information given is still correct. It is guaranteed that it is possible to satisfy all the constraints.

Input
Line 1: Four space-separated integers: N, I, H and R
Lines 2…R+1: Two distinct space-separated integers A and B (1 ≤ A, B ≤ N), indicating that cow A can see cow B.

Output
Lines 1…N: Line i contains the maximum possible height of cow i.

Sample Input
9 3 5 5
1 3
5 3
4 3
3 7
9 8

Sample Output
5
4
5
3
4
4
5
5
5

思路:先把所有牛的身高设为最大值(给的下标其实没用 ),给出一对关系(i , j)表示牛i与牛j可以相互看到,即中间的牛严格比i和j小(小个1就行因为牛的身高尽可能大)。使用一个差分数组处理,c[i + 1]上加1,c[j]减一。则可以达到(i , j)中间的牛[i + 1 ~ j - 1] - 1 的效果。
细节问题:此题中给出的关系对可能存在重复。

#include<bits/stdc++.h>
using namespace std;
const int N = 10010;//牛最多多少个
int c[N];//牛的差分序列
map<pair<int,int>, bool>existed;//判断关系对是否存在重复

int main() {
	int n, p, h, m;
	cin >> n >> p >> h >> m;
	memset(c, 0, sizeof(c));
	for(int i = 1; i <= m; i++) {
		int a, b;
		cin >> a >> b;
		if(a > b)swap(a , b);//保证a比b小,即(a, b)是有效的
		if(existed[make_pair(a, b)])continue;//若关系对之前已判断则不需要再处理
		c[a + 1]--, c[b]++;//处理c[i + 1 ~ j - 1]的牛
		existed[make_pair(a, b)] = true;
	}
	for(int i = 1; i <= n; i++) {
		c[i] += c[i - 1];
		cout << h + c[i] << endl;
	}
	return 0;
}

D-Distinct planks

There is a fence in front of Polycarpus’s home. The fence consists of n planks of the same width which go one after another from left to right. The height of the i-th plank is hi meters, distinct planks can have distinct heights.
在这里插入图片描述

Fence for n = 7 and h = [1, 2, 6, 1, 1, 7, 1]

Polycarpus has bought a posh piano and is thinking about how to get it into the house. In order to carry out his plan, he needs to take exactly k consecutive planks from the fence. Higher planks are harder to tear off the fence, so Polycarpus wants to find such k consecutive planks that the sum of their heights is minimal possible.

Write the program that finds the indexes of k consecutive planks with minimal total height. Pay attention, the fence is not around Polycarpus’s home, it is in front of home (in other words, the fence isn’t cyclic).

Input
The first line of the input contains integers n and k (1 ≤ n ≤ 1.5·105, 1 ≤ k ≤ n) — the number of planks in the fence and the width of the hole for the piano. The second line contains the sequence of integers h1, h2, …, hn (1 ≤ hi ≤ 100), where hi is the height of the i-th plank of the fence.

Output
Print such integer j that the sum of the heights of planks j, j + 1, …, j + k - 1 is the minimum possible. If there are multiple such j’s, print any of them.

Input
7 3
1 2 6 1 1 7 1

Output
3

思路:读不懂题,什么板子(plank)什么名贵的钢琴(posh piano)的? 但是就凭一句find such k consecutive planks that the sum of their heights is minimal possible,翻译过来是找到连续的板子,他们的高度和最小,我们联系输入可以知道题目是求连续k个板子的长度和最小,利用前缀和不难解决。
现在还有一个小问题,就样例而言,样例输出的不是最小值8,而是3。这个3是什么呢?仔细读输出的最后一句话Print such integer j that the sum of the heights of planks j, j + 1, …, j + k - 1 is the minimum possible. ,最小和由k个板子组成,这k个板子中的第一个的下标就是需要输出的答案。

易错:比如ans=i-m+1;写成ans=i-3+1;或者minn=sum[i]-sum[i-m];写成minn=sum[i]-sum[i-3];之类,把样例里m的值直接带进去够你吃几发罚时的。@_@

#include<bits/stdc++.h>
using namespace std;
int v[150010],sum[150010];

int main() {
	int n,m,ans;
		sum[0]=0;
		cin>>n>>m;
		memset(sum,0,sizeof(sum));//好像没必要?
		for(int i=1; i<=n; i++) {
			cin>>v[i];
			sum[i]=sum[i-1]+v[i];
		}
		int minn=INT_MAX;
		for(int i=m; i<=n; i++) {
			if(minn>sum[i]-sum[i-m]) {
				ans=i-m+1;
				minn=sum[i]-sum[i-m];
			}
		}
		cout<<ans<<endl;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值