P2879 [USACO07JAN]區間統計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.

輸入格式

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.

題意翻譯

題目描述:

FarmerJohn 有n頭牛,它們按順序排成一列。 FarmerJohn 只知道其中最高的奶牛的序號及它的高度,其他奶牛的高度都是未知的。現在 FarmerJohn 手上有RR條信息,每條信息上有兩頭奶牛的序號(aa和bb),其中bb奶牛的高度一定大於等於aa奶牛的高度,且aa,bb之間的所有奶牛的高度都比aa小。現在FarmerJohnFarmerJohn想讓你根據這些信息求出每一頭奶牛的可能的最大的高度。(數據保證有解)

輸入格式:

第1行:四個以空格分隔的整數:nn,ii,hh和RR(nn和RR意義見題面; ii 和 hh 表示第 ii 頭牛的高度爲 hh ,他是最高的奶牛)

接下來R行:兩個不同的整數aa和bb(1 ≤ aa,bb ≤ n)

輸出格式:

一共n行,表示每頭奶牛的最大可能高度.

數據範圍:

1 ≤ n ≤ 10000 ; 1 ≤ h ≤ 1000000 ; 0 ≤ R ≤ 10000)

Translate provided by @酥皮

輸入輸出樣例

輸入 #1複製

9 3 5 5
1 3
5 3
4 3
3 7
9 8

輸出 #1複製

5
4
5
3
4
4
5
5
5

剛開始假設每頭牛的身高都最高

牛序號:   1 2 3 4 5 6 7 8 9

初始身高:5 5 5 5 5 5 5 5 5 

1,3說明第1頭牛的身高<=第3頭牛的身高,1-3之間的第2頭牛身高需要減去1

本題需要注意特殊情況,即

9 3 5 7
1 3
1 3
1 3
5 3
4 3
3 7
9 8

此時1 3中的第2頭牛隻需要減一次就行。所以需要對序列進行排序。

#include<iostream>
#include<cmath>
#include<algorithm>
#define N 10005
int a1[N];
using namespace std;
struct node{
	int a;
	int b;
}c[N];
bool cmp(node x, node y)//自定義排序規則,只需要對a的值從小到大排序 
{
	if(x.a <= y.a) return true;
	else return false;
}
int main()
{
	int n,i,h,R;
	cin >> n >> i >> h >> R;
	for(int i = 1; i <= n; ++i) a1[i] = h;//初始情況假設n頭牛的身高都最高 
	for(int i = 1; i <= R; ++i)
	{
		cin >> c[i].a >> c[i].b;
	}
	sort(c+1,c+1+R,cmp);
	/*
	for(int i = 1; i <= R; ++i)
	{
		cout << c[i].a << " " << c[i].b << endl; 
	}
	cout << endl;
	*/
	for(int i = 1; i <= R; ++i)
	{
		if(c[i].a == c[i-1].a && c[i].b == c[i-1].b) continue;//如果和前一個區間相等,則不計算進去 
		if(c[i].a <= c[i].b)//a~b範圍內的值減少1 
		{
			for(int j = c[i].a+1; j <= c[i].b-1; ++j)
			{
				a1[j]-=1;//本步驟可以使用差分進行優化
			}
		}
		else if(c[i].a > c[i].b)
		{
			for(int j = c[i].b+1; j <= c[i].a-1; ++j)
			{
				a1[j]-=1;
			}
		}
		
	}
	for(int i = 1; i <= n; ++i) cout << a1[i] << endl;
	return 0;
 } 

使用map去重 

#include<iostream>
#include<cstdio>
#include<map>
#include<algorithm>
#define N 10005
using namespace std;
map<int,int> m[N];
int a1[N];
int main()
{
	int n,i1,h,R;
	cin >> n >> i1 >> h >> R;
	int a,b;
	for(int i = 1; i <= n; ++i) a1[i] = h;
	while(R--)
	{
		cin >> a >> b;
		if(a>=b) swap(a,b);
		if(m[a][b]) continue;
		else m[a][b] = 1;
		for(int i = a+1; i <= b-1; ++i)
			a1[i] -= 1;
	}
	for(int i = 1; i <= n; ++i) cout << a1[i] << endl;
	return 0;
} 

 

使用差分和前綴和的解法,使用map去重。複雜度降低。

 

#include <stdio.h>
#include <algorithm>
#include <map>
using namespace std;
const int maxn = 100001 ;
map<int,int> mp[maxn] ;
int n,m,id,h,x,y ;
int f[maxn] ;
int main()
{
    scanf("%d%d%d%d",&n,&id,&h,&m ) ;
    for(int i=1;i<=m;i++) 
    {
        scanf("%d%d",&x,&y) ;
        if(x>y) swap(x,y) ; 
        if(mp[x][y]) continue ;
            else mp[x][y]=1 ;
        f[x+1]--;   f[y]++;//差分
    }
    for(int i=1;i<=n;i++) 
    {
        f[i] = f[i]+f[i-1] ;//前綴後得到原數組
        printf("%d\n",f[i]+h) ;
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章