710 div3 时隔多久再次ak

D
大意就是让你 一次可以反转两张不同样的牌 直到反转到不能反转了 问你最少剩下几张反转
由于数据比较大 1e9 所以一个离散化就完事了

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 2e5 + 10;

int a[N],b[N],c[N];

int main(){
	int t;
	cin >> t;
	while(t--){
		int n;
		cin >> n;
		for(int i = 1; i <= n; i++){
			scanf("%d",&a[i]);
			b[i] = a[i];
		}
		
		sort(b + 1,b + n + 1);
		
		int cnt = unique(b + 1,b + n + 1) - b - 1;
		
		for(int i = 1; i <= n; i++){
			a[i] = lower_bound(b + 1,b + cnt + 1,a[i]) - b;
			c[a[i]]++;
		}
		
		bool flag = false;
		for(int i = 1; i <= cnt; i++){
			if(c[i] > n / 2){
				flag = true;
				cout << c[i] - (n - c[i]) << endl;
				break;
			}
		}
		
		for(int i = 1; i <= cnt; i++){
			c[i] = 0;
		}
		
		if(flag) continue;
		else{	
			if(n % 2 == 0) cout << 0 << endl;
			else cout << 1 << endl;
		}
		
	}
	
	
	
	
	
	return 0;
}

E
就是个模拟昂
让你找最大的字典序和最小的字典序
如果是最大的那肯定是从大到小排就行了
那么我们使用vector 来存储 用掉了就删掉就好了
从小到大排的话 直接 一个数组 记录有没有存过就行

#include<iostream>
#include<vector>

using namespace std;

const int N = 2e5 + 10;

int a[N],flag[N];

vector<int>v;

int main(){
	int t;
	cin >> t;
	while(t--){
		int n;
		cin >> n;
		for(int i = 1; i <= n; i++){
			scanf("%d",&a[i]);
		}
		
		int last = 1;
		printf("%d",a[1]);
		flag[a[1]] = 1;
		for(int i = 2; i <= n; i++){
			if(a[i] == a[i - 1]){
				while(flag[last]) last++;
				flag[last] = 1;
				cout << " " << last;
			}else{
				flag[a[i]] = 1;
				cout << " " << a[i];
			}
		}
		cout << endl;
		
		for(int i = 1; i <= n; i++){
			flag[i] = 0;
		}
		
		printf("%d",a[1]);
		for(int i = 1; i < a[1]; i++){
			v.push_back(i);
		}
		last = a[1];
		for(int i = 2; i <= n; i++){
			if(a[i] == a[i - 1]){
				cout << " " << v[v.size() - 1];
				v.erase(--v.end());
			}else{
				cout << " " <<  a[i];
				for(int j = last + 1; j < a[i]; j++){
					v.push_back(j);
				}
				last = a[i];
			}
		}
		cout << endl;
		
		
	}
	
	
	
	
	
	return 0;
}

F
自己画画图就是个规律题

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 2e5 + 10;

struct node{
	int a,b;
	bool operator <(const node &p){
		if(a - b == p.a - p.b) return b < p.b;
		return a - b < p.a - p.b;
	}
}c[N];

int main(){
	int t;
	cin >> t;
	while(t--){
		int n;
		cin >> n;
		for(int i = 1; i <= n; i++){
			scanf("%d",&c[i].a);
		}
		
		for(int i = 1; i <= n; i++){
			scanf("%d",&c[i].b);
		}
		
		sort(c + 1,c + n + 1);
		
		c[0].a = 1,c[0].b = 1;
		
		int last = 0,sum = 0;
		for(int i = 1; i <= n; i++){
			if(c[i].a - c[i].b == last){
				if((c[i].a - c[i].b) % 2 == 0){
					sum += c[i].b - c[i - 1].b;
				}
			}else{
				if(last % 2 == 0){
					sum += (c[i].a - c[i].b - c[i - 1].a + c[i - 1].b) / 2;
					last = c[i].a - c[i].b;
				}else{
					sum += (c[i].a - c[i].b - c[i - 1].a + c[i - 1].b + 1) / 2;
					last = c[i].a - c[i].b;
				}
			}
		}
		cout << sum << endl;
	}
	
	
	
	
	
	
	return 0;
}
/*8
14 15 8 4 13 3 1 10
6 6 5 2 6 1 1 6
5
*/ 

G

此题也是找最大字典序
那我们可以想要先找到最大的然后存下
那么那个最大的前面的数都是需要被删掉的 所以他们出现的次数必须 >= 2
若出现了次数1的 那必然要退出
如果这个次数
1的比之前都大 那么把之前的都删掉就行了
如果比次数==1的比之前的小 那么直接退出 存掉之前那个就行
如何判断这个数有没有被删掉过 那么我们需要搞一个数组去判断
如果现在的遇到的数是最后一个位置的而且没有被输出国的时候那么 必须放上去了 因为每个数都必须出现一次 那就直接退出输出就好了

#include<iostream>
#include<cstring> 

using namespace std;

const int N = 30;

int b[N],flag[N],st[200010],nex[N];

int main(){
	int n;
	cin >> n;
	string a;
	
	for(int i = 1; i <= n; i++){
		memset(b,0,sizeof b);
		memset(flag,0,sizeof flag);
		cin >> a;
		for(int j = 0; j < a.length(); j++){
			b[a[j] - 'a']++;
			nex[a[j] - 'a'] = j;
		}
		
		int k = 27;
		int last = -1;
		while(k--){
			int maxn = -1;
			for(int j = 0; j < a.length(); j++){
				if(st[j] || flag[a[j] - 'a']) continue;
				if(maxn == -1){
					if(nex[a[j] - 'a'] == j){
						maxn = j;
						break;
					}else{
						maxn = j;
					}
				}else{
					if(nex[a[j] - 'a'] == j){
						if(a[maxn] < a[j]){
							maxn = j;
						}
						break;
					}else{
						if(a[maxn] < a[j]){
							maxn = j;
						}
					}
				}
			}
			for(int j = 0; j <= maxn; j++){
				st[j] = 1;
			}
			if(maxn != -1){
				flag[a[maxn] - 'a'] = 1;
				cout << a[maxn];
			} 
		}
		cout << endl;
		for(int i = 0; i < a.length(); i++){
			st[i] = 0;
		}
	}
	
	
	
	
	
	
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值