1.A [HNOI2003]激光炸弹
链接:https://ac.nowcoder.com/acm/contest/999/A
来源:牛客网
一种新型的激光炸弹,可以摧毁一个边长为R的正方形内的所有的目标。
现在地图上有n(N ≤ 10000)个目标,用整数Xi,Yi(其值在[0,5000])表示目标在地图上的位置,每个目标都有一个价值。
激光炸弹的投放是通过卫星定位的,但其有一个缺点,就是其爆破范围,即那个边长为R的正方形的边必须和x,y轴平行。
若目标位于爆破正方形的边上,该目标将不会被摧毁。
输入描述:
输入文件的第一行为正整数n和正整数R,接下来的n行每行有3个正整数,分别表示 xi,yi ,vi 。
输出描述:
输出文件仅有一个正整数,表示一颗炸弹最多能炸掉地图上总价值为多少的目标(结果不会超过32767)。
示例1
输入
2 1
0 0 1
1 1 1
输出
1
备注:
对于100%的数据,保证 1≤n≤10^4,0≤xi,yi≤5×10^3,1≤m≤5×10^3,1≤vi<100。
思路: 二维差分
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
const int maxn=5010;
int maps[maxn][maxn];
int val[maxn][maxn];//计算前缀和
int main()
{
int T;
int R;//炸弹边界
cin>>T;
cin>>R;
int xx=R,yy=R;//确认地图边界
int x,y,w;
while (T--){
cin>>x>>y>>w;
x++;
y++;//将初始坐标改为(1,1)开始
maps[x][y]=w;
xx=max(x,xx);
yy=max(y,yy);//初始化边界
}
for(int i=1;i<=xx;i++)//计算前缀和
for(int j=1;j<=yy;j++){
val[i][j]=val[i-1][j]+val[i][j-1]-val[i-1][j-1]+maps[i][j];
}
int ans=0;//计算炸弹所能花费的最大价值
for(int i=R;i<=xx;i++)
for(int j=R;j<=yy;j++){
ans=max(ans,val[i][j]-val[i-R][j]-val[i][j-R]+val[i-R][j-R]);
}
cout<<ans;
return 0;
}
2.B IncDec Sequence
链接:https://ac.nowcoder.com/acm/contest/999/B
来源:牛客网
题目描述
给定一个长度为 n(n≤10^5) 的数列a1,a2,…,an;
每次可以选择一个区间 [l,r],使下标在这个区间内的数都加一或者都减一。
,并求出在保证最少次数的前提下,最终得到的数列可能有多少种。
输入描述:
第一行一个正整数n。
接下来n行,每行一个整数,第i+1行的整数表示aia_iai。
输出描述:
第一行输出最少操作次数。
第二行输出最终能得到多少种结果。
示例1
输入
1
2
2
输出
1
2
备注:
对于100%的数据,n=100000,0≤ai<21474836480 \leq ai \lt 21474836480≤ai<2147483648
思路
参考博客:https://shineeternal.blog.csdn.net/article/details/101078881
❓
为什么要让 d[2]~d[n] 为0,因为对差分数组进行前缀和的话,只有d[2]~d[n]为0,计算的结果才相等。
question: 所以我们要进行多少次操作呢? max( 正数的和,负数绝对值的和) 为什么呢?
因为你每次在原数组的操作是一个区间[l,r] 体现在差分数组上面就是d[l]+1 d[r+1]-1(或者d[l]-1 d[r+1]+1)
因为每次操作只能对一个正数-1 一个负数+1 所以需要 min( 正数的和,负数绝对值的和)
如果还有剩余的正数或者负数 我们视为[l,l]的+1 或者 -1 即为它们的差值 abs(正数的和 - 负数绝对值的和).
min( 正数的和,负数绝对值的和)+abs(正数的和 - 负数绝对值的和) = max( 正数的和,负数绝对值的和)
question:第二问怎么计算呢?
也就是更改首位元素的值的方案
接着上一问的一个线索,假如还有剩余的正数。
比如当前的差分序列 为 d[1]:4 d[2]:0 d[3]:2 d[4]:0
那么我们就有两种选择,要不自己消掉,要不和d[1]对消。
即自己对消的话 d[1]:4
和d[1]对消1次 d[1]:5
和d[1]对消2次 d[1]:6
所以就是 abs(正数的和 - 负数绝对值的和)+1
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
int Sequence[maxn];
int main()
{
int T;
cin>>T;
long long pos;
long long neg;
pos=0;
neg=0;
for(int i=1;i<=T;i++)
cin>>Sequence[i];
for(int i=2;i<=T;i++){
if(Sequence[i]-Sequence[i-1]>0)
pos+=Sequence[i]-Sequence[i-1];
else
neg-=Sequence[i]-Sequence[i-1];
}
cout<<max(pos,neg)<<endl<<abs(pos-neg)+1<<endl;
}
3.C Tallest Cow
链接:https://ac.nowcoder.com/acm/contest/999/C
来源:牛客网
题目描述
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.
输入描述:
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.
输出描述:
Lines 1..N: Line i contains the maximum possible height of cow i.
示例1
输入
9 3 5 5
1 3
5 3
4 3
3 7
9 8
输出
5
4
5
3
4
4
5
5
5
题意描述:
FarmerJohn 有n头牛,它们按顺序排成一列。 FarmerJohn 只知道其中最高的奶牛的序号及它的高度,其他奶牛的高度都是未知的。现在 FarmerJohn 手上有RRR条信息,每条信息上有两头奶牛的序号(a和b),其中b奶牛的高度一定大于等于a奶牛的高度,且a,b之间的所有奶牛的高度都比a小。现在FarmerJohn想让你根据这些信息求出每一头奶牛的可能的最大的高度。(数据保证有解)
输入格式:
第1行:四个以空格分隔的整数:n,i,h和R(n和R意义见题面; i 和 h 表示第 i 头牛的高度为 h ,他是最高的奶牛)
接下来R行:两个不同的整数a和b(1 ≤ a,b ≤ n)
输出格式:
一共n行,表示每头奶牛的最大可能高度.
思路:
两个可以望见的牛之间的牛的身高是严格小于的,所以两头牛之间的身高都要减1,用前缀和维护
有可能会出现重复的数据,要进行判断重复
#include<stdio.h>
#include<iostream>
#include<math.h>
#include<stdlib.h>
#include<algorithm>
#include<map>
using namespace std;
const int maxn=1e5+5;
map<pair<int,int>,bool> book;
int Sequence[maxn];
int main()
{
int n,i,h,r;
cin>>n>>i>>h>>r;
int x,y;
for(int j=1;j<=r;j++){
cin>>x>>y;
if(x>y) swap(x,y);
if(book[make_pair(x,y)]) continue;
book[make_pair(x,y)]=1;
Sequence[x+1]--;
Sequence[y]++;
}
for(int j=1;j<=n;j++){
Sequence[j]=Sequence[j-1]+Sequence[j];
cout<<Sequence[j]+h<<endl;
}
}