20201111大模拟(二)

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

(还是没看,先挖个坑

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值