K-Dominant Character && C. Ilya and Sticks

34 阅读2分钟

11传送门

[题22传送门](Problem- 525C - Codeforces)

QAQQAQ气死了,为什么调不了啊啊啊啊啊啊啊啊凸(艹皿艹 )。 好吧,今天其实是两个CFCFCC题,一个是div2div2场一个是EduEdu场。

题1思路

一眼发现是二分,关键在于我第一次写的二分时间复杂度还是超了,思路很简单,二分kk,但是如果二分之后暴力枚举每个字母的是否满足这个kk,那么就算经过小的剪枝优化,那么时间复杂度依然高达O(26nlog2n)O(26nlog^2n),这个复杂度就比较性感,我当时算的是可以过的,但是忘了考虑find()find()的时间复杂度,于是乎时间复杂度计算错误,成功在test26test26 TLETLE了,后来找题解发现确实是二分,但是可以用一个大小为2626resres数组在一路遍历的时候记录,因为我们知道对于每个字母xx,那么xx可以管辖的区间就是[xm,x+m][x-m,x+m],但是由于我们是从前往后跑,所以只要考虑前一个区间,我们只需要对每个i>=m1i>=m-1ii,如果这个区间某个字母出现次数为00,那么这个区间一定不满足,然后把m1m-1之前出现的字母次数--。最后我们看看有没有字母能不能满足跑下来,如果有那么我们就returnreturn truetrue。否则我们就returnreturn falsefalse

代码

#include <bits/stdc++.h>

#define ll long long

#define x first
#define y second

using namespace std;
string s;
int len;
bool flag[26];
int res[26];
bool check(int m){
	memset(flag,0,sizeof flag);
	memset(res,0,sizeof res);
	
	for(int i=0;i<len;i++){
		res[s[i]-'a']++;
		if(i>=m-1){
			for(int j=0;j<26;j++){
				if(res[j]==0) flag[j]=true;
			}
			res[s[i-m+1]-'a']--;
		}
	}
	
	for(int i=0;i<26;i++){
		if(!flag[i]) return true;
	}
	return false;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr); 
	
	cin>>s;
	len=s.size();
	int l=1,r=len;
	int ans=0; 
	while(l<r){
		int mid=l+r>>1;
		if(check(mid)) r=mid;
		else l=mid+1;
	}
	cout<<l;
	return 0;
}

题2思路

这题是个贪心,我们降序排序所有的边,然后我们看相邻的边是否满足abs()<=1abs(后-前)<=1满足就把较短的边变成长,然后找宽,找到之后把长和宽再变成00,最后输出答案即可。是个模拟++贪心。

代码

#include <bits/stdc++.h>

#define ll long long

#define x first
#define y second

using namespace std;
ll ans=0;
int n;
ll w[100010];
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr); 
	cin>>n;
	for(int i=1;i<=n;i++) cin>>w[i];
	sort(w+1,w+n+1);
	reverse(w+1,w+n+1); 
	ll l=w[1],r=-1;
	int cntl=1,cntr=0;
	for(int i=2;i<=n;i++){
		if(cntl<2){
			if(cntl==0){
				l=w[i];
				cntl++;
			}
			else if(w[i]==l || w[i]+1==l){
				cntl++;
				l=w[i];
			}
			else{
				l=w[i];
			}
		}
		else if(cntr<2){
			if(cntr==0){
				r=w[i];
				cntr++;
			}
			else if(w[i]==r || w[i]+1==r){
				cntr++;
				r=w[i];
			}
			else r=w[i];
		}
		if(cntl==2 && cntr==2){
			cntl=0,cntr=0;
			ans+=l*r;
		}
	}
	cout<<ans;
	return 0;
}