Educational Codeforces Round 93 (Rated for Div. 2)ABCD

A. Bad Triangle

题意: 问是否有不能组成三角形的情况
思路:因为是有序的,所以用最小的两个和最大的组合查看是否是三角形即可

传送门

#include
using namespace std;
const int maxn=5e4+100;
int t;
int a[maxn];
int main(){
	scanf("%d",&t);
	while(t--){
		int n;scanf("%d",&n);
		for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
		if(a[1]+a[2]<=a[n]){
			printf("1 2 %d\n",n);
		}
		else{
			printf("-1\n");
		}
	}
}

B. Substring Removal Game

传送门

题意:两个人比赛,问在特定规则下A最多可以取多少‘1’
做法:预处理一下,每次都取最大的.两个代码大同小异

#include
using namespace std;
int t;
priority_queue<string> q;
int main(){
	scanf("%d",&t);
	while(t--){
		int sum=0;
		while(!q.empty()) q.pop();
		string s;
		string s1;
		cin>>s;
		int len=s.length();
		for(int i=0;i<len;){
			if(s[i]=='0'){
				if(!s1.empty()){
					q.push(s1);
					s1.clear();
				}
			}
			else s1+='1';
			i++;
		}
		if(s1[0]=='1') q.push(s1);
		int cnt=1;
		while(!q.empty()){
			if(cnt&1){
				sum+=q.top().size();
			}
			cnt++;
			q.pop();
		}
		printf("%d\n",sum);
	}
}
#include
using namespace std;
const int maxn=200;
char s[maxn];
int t;
priority_queue<int> q;
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%s",(s+1));
		int len=strlen(s+1);
		int tot=0;
		for(int i=1;i<=len;){
			if(s[i]=='0'&&tot) q.push(tot),tot=0;
			else if(s[i]=='1') tot++;
			i++;
		}
		if(tot) q.push(tot);
		if(q.empty()&&s[1]=='1')q.push(len);
			int sum=0;
	int cnt=1;
	while(!q.empty()){
		if(cnt&1){
			sum+=q.top();
		}
		cnt++;q.pop();
	}
	printf("%d\n",sum);
	}
}

C - Good Subarrays

传送门

题意:问多少子数组满足子数组之和等于该子数组的长度。
比赛中没有做出来,看了别人的题解才明白了一点
做法:每一次s[]都减1,将问题转化成了有多少子数组和为0.求出相同的sum[]的个数num,他们的区间的组合有num*(num-1)/2种组合
0要提前加1,前缀和-1为0的区间直接满足

#include
using namespace std;
typedef long long ll;
const int maxn=1e5+10;
int t,n;
int a[maxn];
int sum[maxn];
char s[maxn];
map<int,int> mp;
void solve()
{
	mp.clear();
	memset(a,0,sizeof(a));
	memset(sum,0,sizeof(sum));
		int len=strlen(s+1);
		mp[0]++;
		for(int i=1;i<=len;i++){
			sum[i]=sum[i-1]+s[i]-'0'-1;
			mp[sum[i]]++;
		}
		map<int,int>::iterator it;
		ll cnt=0;
		for(it=mp.begin();it!=mp.end();it++){
			int num=it->second;
			cnt+=1ll*num*(num-1)/2;
		}
		printf("%lld\n",cnt);	
}
int main(){
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		scanf("%s",(s+1));
		solve();
	}
}

D. Colored Rectangles

传送门

题意:用三种不同类型的木棍组成矩形,矩形必须为两种不同类型的木棍。问最大可以组成的矩形和是多少
做法:DP

#include
using namespace std;
const int maxn=220;
int dp[maxn][maxn][maxn];
int a[maxn],b[maxn],c[maxn];
int r,g,d;
int ans;
int main()
{
	scanf("%d%d%d",&r,&g,&d);
	for(int i=1;i<=r;i++)
	scanf("%d",&a[i]);
	for(int i=1;i<=g;i++)
	scanf("%d",&b[i]);
	for(int i=1;i<=d;i++)
	scanf("%d",&c[i]);
	sort(a+1,a+1+r,greater<int>());
	sort(b+1,b+1+g,greater<int>());
	sort(c+1,c+1+d,greater<int>());
	for(int i=0;i<=r;i++){
		for(int j=0;j<=g;j++){
			for(int k=0;k<=d;k++){
				dp[i][j+1][k+1]=max(dp[i][j+1][k+1],dp[i][j][k]+b[j+1]*c[k+1]);
				dp[i+1][j][k+1]=max(dp[i+1][j][k+1],dp[i][j][k]+a[i+1]*c[k+1]);
				dp[i+1][j+1][k]=max(dp[i+1][j+1][k],dp[i][j][k]+a[i+1]*b[j+1]);
				ans=max(ans,dp[i][j+1][k+1]);
				ans=max(ans,dp[i+1][j][k+1]);
				ans=max(ans,dp[i+1][j+1][k]);
			}
		}
	}
	printf("%d\n",ans);
}

你可能感兴趣的:(--------【训练赛】)