Codeforces 401B Sereja and Contests 題解

zhuluoan發表於2024-05-18

題目簡述

Sereja 是一名程式設計師,他喜歡參加 Codesorfes 比賽。不過,烏茲蘭的網路連線不太好,所以 Sereja 有時會跳過比賽。

Codesorfes 有兩種型別的比賽,分為 Div1 和 Div2。 Div1 和 Div2 這兩輪可以同時進行(Div1 輪不能在沒有 Div2 的情況下進行)。每一輪都有一個唯一的識別符號,各輪按開始時間順序編號。同時執行的各輪識別符號相差一個,而且 Div1 輪的識別符號總是較大。

Sereja 是一名初學者,因此他只能參加 Div2 型別的比賽。此刻他正在參與 Div2 回合,其識別符號為 $x$。Sereja 清楚地記得,在這一輪之前,他正好下過 $k$ 輪。此外,他還記得他參加過的各輪比賽的所有識別符號,以及與它們同時進行的各輪比賽的所有識別符號。Sereja 不記得他錯過的任何一輪比賽。

Sereja 想知道他錯過的 Div2 輪最少和最多會是多少?幫他找出這兩個數字。

題目分析

可以先將這 $k+1$ 輪比賽排序,算出每兩輪之間錯過的場數,設為 $a$,如果要是最多,那麼這 $a$ 輪都是 div2。要是最少的話,就要讓 div1 和 div2 同時進行的場數儘可能多,即最多有 $\lfloor \frac{a}{2} \rfloor$ 輪,有可能 $a$ 是奇數,那麼還要多一輪 div2,所以最少的場數就是 $\lfloor \frac{a}{2} \rfloor+a \bmod 2$,累加即可。

程式碼

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define random(a,b) (rand()%(b-a+1)+a)
#define se second
#define fi first
#define pr pair<int,int>
#define pb push_back
#define ph push
#define ft front
#define For(i,a,b) for(int i=a;i<=b;i++)
#define Rep(i,a,b) for(int i=a;i>=b;i--)
#define mem(a,b) memset(a,b,sizeof a)
const int N=4100;
int x,k,opt,ans1,ans2;
pr a[N];
int main()
{
	ios::sync_with_stdio(false);
    cin.tie(0);
    cin>>x>>k;
    For(i,1,k)
    {
    	cin>>opt;
		if(opt==2)
		{
			cin>>a[i].fi;
			a[i].se=a[i].fi;
		}
		else
		{
			cin>>a[i].fi>>a[i].se;
		}
	}
	a[k+1].fi=x;
	sort(a+1,a+1+k);
	For(i,1,k+1)
	{
		int temp=a[i].fi-a[i-1].se-1;
		ans1+=temp/2+(temp%2);
		ans2+=temp;
	}
	cout<<ans1<<" "<<ans2;
	return 0;
}

相關文章