题目描述:
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.
输入样例:
9 3 5 5
1 3
5 3
4 3
3 7
9 8
输出样例:
5
4
5
3
4
4
5
5
5
翻译中文:
问题分析:
即在一堆数量为N的牛中,只告诉了你两个值,一个是最高的牛的高,还有他所处的下标,然后有M次记录,每次记录中都有A B两头牛能够互看到对方,不过B的高是>=A的,而AB中间的牛的高都是至少小1于A与B两者的min高的,通过分析,我们可以画出草图发现
图二
假若是第一张图这种重合的情况,那是不成立的,因为如果这样就出现矛盾了。 所以就只有图二这种情况。
我们不妨设每头牛的高度都为最高的那头牛的高度即H,用一个前缀和数组来存每头牛的高度,然后再M次记录中再对AB之间的牛用前缀和的性质进行修改
例如假设前缀和数组为height[] 一开始让height[1] = H,则可以让后面的牛的高度都为H ,而在M次记录中,想要让AB之间的牛高度-1,那么就只需要说让height[A + 1] -- 和height[B] ++即可,最后问题的输出是输出当前序列每天牛的最大可能高度,所以可以发现上面确实中间的牛的高度最多也就只能是-1的
代码如下:
点击此处看代码
#include <iostream>
#include <set>
using namespace std;
const int N = 100010;
int height[N];//存放高度的前缀和数组
set<pair<int,int>> existed;//用来判断关系对是否重复
int main()
{
int N, P, H, M;
scanf("%d%d%d%d", &N, &P, &H, &M);
height[1] = H;//让前缀和数组后面的高度都为H
for(int i = 0; i < M; i ++ )
{
int A, B;
scanf("%d%d", &A, &B);
if(A > B) swap(A, B);//要确保A的高<=B的高
if(!existed.count({A,B}))//假若之前没有判断此对关系对就执行下面
{
existed.insert({A,B});//将关系对插进来 并执行下面操作
//要让A
height[A + 1] -- , height[B] ++;
}
}
for(int i = 1; i <= N; i ++ )//求差分数组前缀和 即每头牛可能的身高为多少
{
height[i] += height[i - 1];
printf("%d\n", height[i]);
}
return 0;
}