Codeforces Round #790 (Div. 4)

Codeforces Round #790 (Div. 4)

A. Lucky?

题意:

给定一个由六个数字组成的字符串,若前三个数字的总和等于后三个数字,则输出YES,否则输出NO

代码:

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

void solve(){
	string s;
	cin >>s;
	if(s[0]+s[1]+s[2]==s[3]+s[4]+s[5]){
		cout <<"YES\n";
	}else{
		cout <<"NO\n";
	}
}

int main(){
	
	int T;
	cin >>T;
	while(T--){
		solve();
	}
	
	return 0;
}

B. Equal Candies

题意:

将所有盒子中的糖果吃到同一数量

思路:

因为盒子中的糖果不能由少变多,只能由多吃到少。所以最后所有盒子中的糖果一定是最初盒子中的最小值

代码:

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

int n;
int x;

void solve(){
	long long ans = 0;
	int mmin=1e7+1;
	cin >>n;
	for(int i=1;i<=n;i++){
		cin >>x;
		ans+=x;//将所有糖果数量加起来
		mmin=min(mmin,x);//记录所有盒子中糖果最少的数量
	}
	cout <<ans-n*mmin<<endl;//最后每个盒子糖果数量一定为n*mmin
}

int main(){
	
	int T;
	cin >>T;
	while(T--){
		solve();
	}
	
	return 0;
}

C. Most Similar Words

题意:

给定n个长度为m的字符串,将他们进行如下操作:

  • 将一个字母变成前一个字母或者后一个字母,例如:

    可以将e变成df

    a只能变成b

    z只能变成y

问这n个字符串中某两个字符串变成相同字符串操作的最小值

思路:

只需计算每两个字符串中每个位置字母的ASCLL绝对值

代码:

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

void solve(){
	string s[51];
	int n,m;
	cin >>n>>m;
	for(int i=1;i<=n;i++){
		cin >>s[i];
	}
    
	long long num = 0;
	long long ans = 2147483647;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(i==j) continue;//自己不能变成自己
			num = 0;
			for(int k=0;k<m;k++){
				num+=abs(s[i][k]-s[j][k]);
			}
			ans=min(ans,num);
		}
		
	}
	cout <<ans<<endl;
}

int main(){
	
	int T;
	cin >>T;
	while(T--){
		solve();
	}
	
	return 0;
}

D. X-Sum

题意:

n*m大小且给定每个格子的数值的棋盘中任意放一枚棋子,棋子可以攻击所在棋格斜45度方向的所有棋格;例如:

请添加图片描述

棋子可以攻击到图中所有蓝色的棋格。

求:棋子放在任意棋格上,输出棋子可以攻击到棋格上的值的最大值

暴力!

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

int a[201][201];
int n,m;

long long find(int x,int y){//返回棋子放在(x,y)这一点时,攻击到棋格的数值
	long long res = 0;
	res += a[x][y];
	int xx=x,yy=y;
	while(true){//左上角
		if(xx==1||yy==1)	break;
		res+=a[xx-1][yy-1];
		xx--;
		yy--;
	}
	xx=x,yy=y;
	while(true){//右上角
		if(xx==1||yy==m)	break;
		res+=a[xx-1][yy+1];
		xx--;
		yy++;
	}
	xx=x,yy=y;
	while(true){//左下角
		if(xx==n||yy==1)	break;
		res+=a[xx+1][yy-1];
		xx++;
		yy--;
	}
	xx=x,yy=y;
	while(true){//右下角
		if(xx==n||yy==m)	break;
		res+=a[xx+1][yy+1];
		xx++;
		yy++;
	}
	return res;
}

void solve(){
	
	cin >>n>>m;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin >>a[i][j];
		}
	}
    
	long long ans = 0;
    //遍历每个棋格
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			ans = max(ans,find(i,j));
		}
	}
	cout <<ans<<endl;
}

int main(){
	
	int T;
	cin >>T;
	while(T--){
		solve();
	}
	
	return 0;
}

优化:

计算每个单元格的所有对角线总和。


E. Eating Queries

题意:

给定n个有甜度的糖果,并询问m次,每次给定一个值num

要求:

每次询问输出一个值x,代表最少吃x个糖果,甜度就可以达到num

思路:

数据范围为1.5*10^5;

如果暴力O(n^2)会超过题目要求的3.5s

若使用前缀和代表若干个糖果可以达到的最大甜度,加二分查找数值num,则O(nlogn)可以通过(要什么自行车)。

代码:

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

bool cmp(int a,int b){
	return a>b;
}

int a[1000006];

void solve(){
	int n,m;
	cin >>n>>m;
	for(int i=1;i<=n;i++){
		cin >>a[i];
	}
	sort(a+1,a+1+n,cmp);
	for(int i=1;i<=n;i++){
		a[i]=a[i-1]+a[i];//a[i]表示i个糖果可以达到的最大值
	} 
	while(m--){
		int x;
		cin >>x;
		cout <<((lower_bound(a+1,a+1+n,x)-a)>n?-1:(lower_bound(a+1,a+1+n,x)-a))<<endl;//使用lower_bound()得出答案。
	}
}

int main(){
	
	int T;
	cin >>T;
	while(T--){
		solve();
	}
	
	return 0;
}

F. Longest Strike

题意:

给定n个数字,求一个[l,r]表示:lr中每个数字均出现至少k次,且r-l最大;

例如:

7 2
11 11 12 13 13 14 14

其中:11 13 14均出现3次,但是11-11小于14-13

故答案为:

13 14

暴力嘛,不丢人(doge)

思路及代码:

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

void solve(){
	int n,k;
	cin >>n>>k;//读入数据
	
	map<int,int> ma;
	ma.clear();//初始化
	
	for(int i=1;i<=n;i++){
		int x;
		cin >>x;
		ma[x]++;
	}//将每个数字出现的次数读入
	
	int ans = 0;
	int l=-1,r=-1,ll=-1,rr=-1;
	bool pd = false;//判断l是否已经有了数值
	int num=0;
	
	for(map<int,int>::iterator i=ma.begin();i!=ma.end();i++){
		if(i->second>=k){//如果该数字出现的次数大于等于k,则进入判断
			if(pd&&i->first==num+1){//若l已经有数值,且范围连续
				num++;
				r=i->first;
				if(r-l>=ans){
					rr=r;
					ll=l;
					ans=r-l;
				}
			}
			else if(pd&&i->first!=num+1){//若l已经有了数值,但范围不连续
				l=i->first;//将l重新赋值
				num=l;
			}
			else if(pd==false){//若l没有数值
				r=i->first;
				l=i->first;
				if((r-l)>=ans){
					rr=r;
					ll=l;
				}
				pd=true;
				num=i->first;
			}
			else{
				if((r-l)>=ans){
					ans = r-l;
					ll=l;
					rr=r;
				}
				pd=false;
				l=i->first;
				num=l;
			}
		}else{//若不大于则说明l到r的范围一定被打断
			if(pd==false)	continue;
			pd=false;
			map<int,int>::iterator p=i;
			p--;
			r=p->first;//将被打断之前的l和r记录
			if((r-l)>=ans){
				ans = r-l;
				ll=l;
				rr=r;
			}
		}
	}
	
	if(ll==-1||rr==-1){//都不满足要求,则输出-1
		cout <<-1<<endl;
		return;
	}
	cout <<ll<<" "<<rr<<endl;
	return;
}

int main(){
	
	int T;
	cin >>T;
	while(T--){
		solve();
	}
	
	return 0;
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值