Educational Codeforces Round 114 (Rated for Div. 2) A~D題解


本場鏈接:Educational Codeforces Round 114 (Rated for Div. 2)

A. Regular Bracket Sequences

由於只需要構造 \(n\) 種,所以構造第 \(i\) 的時候可以讓最左端的是一個長度為 \(i\) 的大括號,后面的可以任意。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
#define x first
#define y second

int main()
{
	int T;scanf("%d",&T);
	while(T--)
	{
		int n;scanf("%d",&n);
		forn(i,1,n)
		{
			forn(j,1,i)	printf("(");
			forn(j,1,i)	printf(")");
			forn(j,1,n - i)	printf("()");
			puts("");
		}
	}
	return 0;
}
		

B. Combinatorics Homework

求出:最多構造的個數和最少構造的個數,由於具體形態其實並不重要,不妨調整三個數使得: \(a \geq b \geq c\)。這樣構造:AAAABBBBCCCC顯然總是個數最多的方案。構造:ABABABABACACAC...這樣總是最少的。考慮 \(m\) 是否是可達的:從最多的方案中把一個 \(B/C\)放到開頭的 A中去可以導致答案恰好減少一個,所以只要 \(m\) 處於最大值和最小值之間,總是可達的。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
#define x first
#define y second

int a[10];

int main()
{
	int T;scanf("%d",&T);
	while(T--)
	{
		forn(i,1,3)	scanf("%d",&a[i]);
		int m;scanf("%d",&m);
		sort(a + 1,a + 3 + 1);reverse(a + 1,a + 3 + 1);
		if(m >= a[1] - a[2] - a[3] - 1 && m <= a[1] + a[2] + a[3] - 3)	puts("YES");
		else puts("NO");
	}
	return 0;
}
		

C. Slay the Dragon

每個問題獨立,對於每個問題顯然我們只關注: \(a_p \geq x\) 且最小的 \(a_p\) 以及 \(a_p < x\) 且最大的 \(a_p\)

求出對應的 \(p\) 算出答案即可。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
#define x first
#define y second

const int N = 2e5+7;
ll a[N];

int main()
{
	int n;scanf("%d",&n);
	ll sum = 0;
	forn(i,1,n)	scanf("%lld",&a[i]),sum += a[i];
	sort(a + 1,a + n + 1);a[0] = -1e18;a[n + 1] = 1e18;

	int m;scanf("%d",&m);
	while(m--)
	{
		ll x,y;scanf("%lld%lld",&x,&y);
		int p = lower_bound(a + 1,a + n + 1,x) - a;
		ll res = 2e18;
		if(p <= n)	res = min(res,max(0ll,y - sum + a[p]));
		--p;
		if(p >= 1)	res = min(res,max(0ll,y - sum + a[p]) + x - a[p]);
		printf("%lld\n",res);
	}
	return 0;
}
		

D. The Strongest Build

顯然一點:每個位置都取最大值總是一個最牛逼的狀態,但是這樣的狀態不總是可以達到的。如何求出一個可行的答案?考慮遍歷答案:每次把當前的答案中的一個還可以減少的位置減一,這樣每個狀態每次拓展的時候都會獲得至多 \(n\) 個新狀態。從最開始最牛逼的狀態往下遍歷求最優解可以對應到求最短路上。這樣跑 dijkstra 即可。

時間復雜度:不會,感性理解一下:本來沒得限制條件的話一開始就是最大的,但是有了之后最多也就拓展出 \(m+1\) 個狀態,雖然單個狀態每次拓展的時候會直接拓展出至多 \(n\) 個新狀態,但是對整個的復雜度影響不會很大,因為 \(n\) 的值太小了。

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
#define forn(i,x,n) for(int i = x;i <= n;++i)
#define forr(i,x,n) for(int i = n;i >= x;--i)
#define Angel_Dust ios::sync_with_stdio(0);cin.tie(0)
#define x first
#define y second

const int N = 2e5+7,M = 17;
int a[M][N],siz[M];

struct Node
{
	int w;
	vector<int> vals;
	Node (vector<int>& oth)
	{
		w = 0;
		vals = oth;
		forn(i,0,vals.size() - 1)	w += a[i + 1][vals[i]];
	}

	bool operator<(const Node& rhs)	const
	{
		if(w != rhs.w)	return w < rhs.w;
		forn(i,0,vals.size() - 1)	if(vals[i] != rhs.vals[i])	return vals[i] < rhs.vals[i];
		return 0;
	}

	bool operator>(const Node& rhs)	const
	{
		if(w != rhs.w)	return w > rhs.w;
		forn(i,0,vals.size() - 1)	if(vals[i] != rhs.vals[i])	return vals[i] > rhs.vals[i];
		return 0;
	}

	bool operator==(const Node& rhs)	const
	{
		if(w != rhs.w)	return 0;
		forn(i,0,vals.size() - 1)	if(vals[i] != rhs.vals[i])	return 0;
		return 1;
	}
};

map<Node,int> st,ban;

int main()
{
	int n;scanf("%d",&n);
	forn(i,1,n)
	{
		scanf("%d",&siz[i]);
		forn(j,1,siz[i])	scanf("%d",&a[i][j]);
	}

	int m;scanf("%d",&m);
	forn(i,1,m)
	{
		vector<int> oth(n);
		for(auto& _ : oth)	scanf("%d",&_);
		Node banp(oth);
		ban[banp] = 1;
	}

	vector<int> best(n);
	forn(i,1,n)	best[i - 1] = siz[i];
	Node STT(best);

	priority_queue<Node,vector<Node>,less<Node>> pq;pq.push(STT);
	while(!pq.empty())
	{
		auto u = pq.top();pq.pop();
		if(st[u])	continue;
		st[u] = 1;
		
		if(!ban.count(u))
		{
			for(auto& _ : u.vals)	printf("%d ",_);
			puts("");
			return 0;
		}

		Node v = u;
		forn(i,0,n - 1)
		{
			if(v.vals[i] == 1)	continue;
			--v.vals[i];
			v.w -= a[i + 1][v.vals[i] + 1] - a[i + 1][v.vals[i]];
			pq.push(v);
			v.w += a[i + 1][v.vals[i] + 1] - a[i + 1][v.vals[i]];
			++v.vals[i];
		}
	}
	return 0;
}
		


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM