1. 程式人生 > 其它 >Education div2 1469總結及補題

Education div2 1469總結及補題

技術標籤:訓練題解演算法

A題是真坑爹呀
啊啊
You are given a sequence s of n characters (, ), and/or ?. There is exactly one character ( and exactly one character ) in this sequence.
誰能想到這句話的意思是這個字串中只包含一個左括號和一個右括號
aiaiai,怪不得我覺得別人的程式碼有問題。

B題
題意是,給兩個字串,組合成一個字串,但是相對順序不能改變。求最大字首和。直接把第一個字串和第二個字串的最大字首和加起來就行。我去看一下dp怎麼寫
部分人都是思維寫的,dp太簡單了,

C題
題意是有凹凸不平的地面,有n個長度為k的寬度 為1的柱子吧。要求至少所有的柱子有一個公共的邊,然後你可以提高k-1範圍內的高度
如上
問能否滿足條件。
注:第一個和最後一個不能升高

  • 思路
    由於第一個位置已經確定,那麼第二個的位置範圍肯定確定了。一次類推都可以確定一個範圍,如果這個範圍長度為0或者為負,那必然不滿足題意了
#include <iostream>
#include <vector>
#include <queue>
#include <stack>
const int N = 2e5+10;

using namespace std;
int h[N],f_h[N]; void solve() { int n,k; cin>>n>>k; for(int i=1;i<=n;i++) { cin>>h[i]; } bool judge=false; int l=h[1],he=h[1]; for(int i=2;i<=n;i++) { l-=k-1; he+=k-1; l=max(l,h[i]); he=min(he,h[i]+k-1); if(l>he) {
judge=true; break; } } if(h[n]<l||h[n]>he) judge=true; if(judge) cout<<"NO"<<endl; else { cout<<"YES"<<endl; } } int main() { int t; cin >> t; while (t--) { solve(); } }

雖然是借鑑別人的思路,但是自己確實想明白了,(想明白了80%~90%吧)垃圾嗚嗚嗚嗚。

D題
題意,一個長度為n的陣列,Ai=i;
每次操作,取x,和y兩個下標,不相等,然後Ax=Ax/Ay上取整;
問能否在最後陣列有n-1個1,1個2
最多操作不能超過n+5次 。
思路:
自然的想法就是把x分別取3,4,…,n−1,y=n,最後取x=n,y=2,但這樣的運算元是n−3+log2n,n較大時,超過了n+5。

因為x為n,y為2的運算元過多,我們設法讓y變大一點,比如y取15,這樣log15n就不超過5了,而log215也最多4,多試幾個數就能過了。(想精確的可以列出式子logxn+log2x求個最值)

也就是x=3,4,…,b−1,b+1,…,n−1,y=n,然後x=n,y=b,直到第n個數變成1,然後x=b,y=2,直到第b個數變成1。
大佬的一個思路,操一點想到,aaaa,其實想到了已經,但是我取得是20,未嘗不可,沒有想到用pair存起來。。。

#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <cmath>
#include <cstring>
const int N = 2e5 + 10;

using namespace std;


void solve()
{
	vector< pair<int,int> > out;
	int n;
	cin >> n;
	int base=16;
	for(int i=3;i<n;i++)
	{
		if(i==base)
		continue;
		out.push_back({i,n});
	}
	if(n>base)
	{
		int x=n;
		while(x!=1)
		{
			out.push_back({n,base});
			x = ceil(x* 1.0 / base);
		}
		x=base;
		while(x!=1)
		{
			out.push_back({base,2});
			x = ceil(x * 1.0 / 2);
		}
	}
	else
	{
		int x=n;
		while(x!=1)
		{
			out.push_back({n,2});
			x = ceil(x * 1.0 / 2);
		}
	}
	cout<<out.size()<<endl;
	for(int i=0;i<out.size();i++)
	{
		cout<<out[i].first<<" "<<out[i].second<<endl;
	}
}

int main()
{
	//cout<<pow(10,6)<<endl;
	int t;
	cin >> t;
	while (t--)
	{
		solve();
	}
}

ceil用法