20201111大模擬(二)

juraws發表於2020-11-11

20201111大模擬(二)

起碼這次沒有爆零,及時換題yyds

說好的過題產生的興奮能讓別的題也過了的呢(bushi

C似乎還好,因為題目長不想看的習慣得改改

A - Diana and Liana

CodeForces - 1121D

沒有很大模擬吧

做法略奇怪,是把除了(n-1)個人,(前後分配) 中間部分拿出來看能不能滿足,感覺隨機資料的複雜度不會爆炸,就衝了(捱打

剛開始狂T48,想了想自己的複雜度確實會被特殊構造的資料卡掉,比如del(del = m - n * k)很大的時候,特殊判斷就行了,因為(s<k 其他時候可以證明是不會被卡掉的

話說知道自己會卡還因為T就改scanf改unordered_map又亂衝兩發是真的又要捱打襖,可惡,雖然這種題目真的搞心態(?

#include <bits/stdc++.h>
using namespace std;

const int maxn = 5e5 + 10;
int a[maxn];
int b[maxn];

vector<int> ans;
unordered_map<int, int> mp;
int n ,m, k ,s;

		
unordered_map<int, int> mm;
bool fla = 0;

inline bool judge(int le, int ri, int lle, int lri) {
	int del = m - n * k;
	
	if((le < lri && le - ri > del)|| fla == 0) {
		mm.clear();
		fla = 1;
		for(int i = le; i <= ri; ++ i) {
			if(mp.count(a[i])) {
				mm[a[i]] ++;
			}
		}
		
			
	}
	else {
		for(int i = lle; i < le; ++ i) {
			if(mp.count(a[i])) {
				mm[a[i]] --;
			}
		}
		for(int i = lri + 1; i <= ri; ++ i) {
			if(mp.count(a[i])) {
				mm[a[i]] ++;
			}
		}
	}
	
	for(auto x : mp) {
			if(mm[x.first] < x.second) return 0;
		}
	return 1;
}

inline void solve(int le, int ri) {
	int del = m - n * k;
	
	for(int i = le; i <= ri; ++ i) {
		if(mp.count(a[i]) && mp[a[i]] > 0) {
			mp[a[i]] --;
		}
		else {
			if(del <= 0) {
				break;
			}
			ans.push_back(i);
			del --;
		}
	}
}

int main(){
	//int m, k, n, s;
	//cin >> m >> k >> n >> s;
	scanf("%d%d%d%d", &m, &k, &n, &s);
	for(int i = 1; i <= m; ++ i) {
		//cin >> a[i];
		scanf("%d", &a[i]);
	}
	for(int i = 1; i <= s; ++ i) {
		//cin >> b[i];
		scanf("%d", &b[i]);
		mp[b[i]] ++;
	} 
	
	bool f = 0;
	
	int del = m - n * k;
	
	for(int i = 0; i <= n - 1; ++ i) {
		int le = i * k + 1;
		int ri = i * k + del + k;
		int lle = (i - 1) * k + 1;
		int lri = (i - 1) * k + del + k;
		if(judge(le, ri, lle, lri)) {
			f = 1;
			solve(le, ri);
			break;
		}
	}
	
	if(!f) {
		//cout << -1;
		printf("-1");
	}
	else {
		//cout << ans.size() << endl;
		int siz = ans.size();
		printf("%d\n", siz);
		for(int i = 0; i < siz; ++ i) {
			//cout << ans[i] << " ";
			printf("%d ", ans[i]);
		}
	}
	
	return 0;
}

B - 雙端佇列

黑暗爆炸 - 2457

這個oj真好,資料全能下載(bushi

反正就是兩個順序,value和index搞來搞去(??

這個思路看過題解了,剛開始碼炸了,是參考網上題解的寫法寫的((

#include <bits/stdc++.h>
using namespace std;

const int maxn = 2e5 + 10;

struct node {
	int idx, val;
}mp[maxn];

bool cmp(node a , node b) {
	if(a.val == b.val) return a.idx < b.idx;
	return a.val < b.val; 
}

vector<pair<int, int> > sam;

int main() {
	//freopen("4.in", "r", stdin);
	int n;
	cin >> n;
	for(int i = 1; i <= n; ++ i) {
		cin >> mp[i].val;
		mp[i].idx = i;
	}
	sort(mp + 1, mp + n + 1, cmp);
	
	sam.clear();
	
	for(int i = 1; i <= n;) {
		int tmp = mp[i].val;
		int pos = i;
		int mx = mp[i].idx, mn = mp[i].idx;
		for(int j = i + 1; j <= n; ++ j) {
			if(mp[j].val == tmp){
				pos = j;
				mn = min(mn, mp[j].idx);
				mx = max(mx, mp[j].idx);
			} 
			else{
				break;
			} 
		}
		sam.push_back({mn, mx});
		i = pos + 1;
	}
	
//	for(auto x : sam) {
//		cout << x.first << " " << x.second << endl;
//	}

	int siz = sam.size();
	
	int ans1 = 0;
	bool f = 0;
	for(int i = 1; i < siz; ++ i) {
		pair<int, int> pre = sam[i - 1];
		pair<int, int> now = sam[i];
		
		if(f == 0) { // dowm
			if(pre.first > now.second) {
				
			}
			else {
				f = 1;
				
			}
		}
		else { // up
			if(pre.second < now.first) {
				
			}
			else {
				f = 0;
				ans1 ++;
				
			}
		}
	}
	
	int ans2 = 0;
	f = 1;
	for(int i = 1; i < siz; ++ i) {
		pair<int, int> pre = sam[i - 1];
		pair<int, int> now = sam[i];
		
		if(f == 0) { // dowm
			if(pre.first > now.second) {
				
			}
			else {
				f = 1;
				
			}
		}
		else { // up
			if(pre.second < now.first) {
				
			}
			else {
				f = 0;
				ans2 ++;
				
			}
		}
	}
	
	//cout << ans1 << " " << ans2 << endl;
	cout << min(ans1, ans2) + 1 << endl; 
} 

C - Steam Roller

UVA - 1078

題目好長,因為題目長不想看的習慣得改改,雖然好像這次還有因為榜剛開始1/12的原因(好像是有人一個人貢獻了10發啥的,emm

(還是沒看,先挖個坑