Codeforces Round #575 (Div. 3) 题解



A. Three Piles of Candies(签到)

原题链接:https://codeforces.com/contest/1196/problem/A


题意: 两个人分三堆糖果,两个人先各拿一堆,然后剩下一堆随意分配,使两个人中最后糖果较少的那个人的糖果最多。

思路: 签到题,求三堆糖果数量平均数。


Code1(C++):

先把三堆糖果数量排个序,然后把最大的一堆比中间那堆多的数量以及最小的一堆的数量相加求平均数再加上中间那堆就是三堆糖果的平均数。

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int main(){
	int n;	cin>>n;
	while(n--){
		ll a[5];
		cin>>a[0]>>a[1]>>a[2];
		sort(a,a+3);
		cout<<a[1]+(a[2]-a[1]+a[0])/2<<endl;
	}
	return 0;
}

Code2(C++):

直接把三堆糖果数量加起来除以2即可。

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
int main(){
	int n;	cin>>n;
	while(n--){
		ll a[5];
		cin>>a[0]>>a[1]>>a[2];
		cout<<(a[0]+a[1]+a[2])/2<<endl;
	}
	return 0;
}

Code3(Java):

import java.util.Scanner;
public class Main {
	static long[] a = new long[5];
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		int n = cin.nextInt();
		while(n-- >0) {
			a[0] = cin.nextLong();
			a[1] = cin.nextLong();
			a[2] = cin.nextLong();
			long ans = (a[0]+a[1]+a[2])/2;
			System.out.println(ans);
		}
	}
}


B. Odd Sum Segments(思维)

原题链接:https://codeforces.com/contest/1196/problem/B

题意: 给出一个n个数的数组,分成k个部分。如果存在每个部分之和为奇数,则输出 “Yes”,并输出每部分的右边界;否则输出 “No”。

思路:

首先需要知道以下数论知识点:

  1. 奇+奇 = 偶
  2. 偶+偶 = 偶
  3. 奇+偶 = 奇

此题分为三种情况:

  1. 奇数个数小于 k,输出 “No” 。
  2. 奇数个数大于等于 k,保证奇数个数的奇偶性与 k 的奇偶性相同则存在。
  3. 奇数个数大于等于 k,奇数个数的奇偶性与 k 的奇偶性不同则不存在。

Code(C++):

#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
vector<int> v;
int main(){
	int q;	cin>>q;
	while(q--){
		v.clear();
		int n,k,x;
		cin>>n>>k;
		for(int i=1;i<=n;i++){
			cin>>x;
			if(x&1)
				v.push_back(i);
		}
		int len=v.size();
		if(len<k)
			cout<<"No"<<endl;
		else if(len%2 == k%2){
			cout<<"Yes"<<endl;
			for(int i=0;i<k-1;i++)
				cout<<v[i]<<" ";
			cout<<n<<endl;
		}
		else
			cout<<"No"<<endl;
	} 
	return 0;
}


C. Robot Breakout(思维)

原题链接: https://codeforces.com/contest/1196/problem/C


题意: 给出n个只能向上下左右四个方向行动的机器人的坐标,但是这些机器人有些故障,可能不能朝某个方向移动,构造一个所有机器人都能到达的坐标。如果不存在这个点,输出 “0”,否则输出 “1”,并输出其中符合条件的一个点的坐标。

思路: 只要划定每个机器人可行的范围,如果均存在共同交界处,则存在。

  1. 确定每个机器人能到达最左端的最大的那个值。
  2. 确定每个机器人能到达最右端的最小的那个值。
  3. 确定每个机器人能到达最上端的最小的那个值。
  4. 确定每个机器人能到达最下端的最大的那个值。

Code(C++):

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1e5;
int x[N+10],y[N+10];
int f[N+10][5];
int main(){
	int q;	cin>>q;
	while(q--){
		int n;	cin>>n;
		int lx=-N,ly=-N,rx=N,ry=N;
		for(int i=1;i<=n;i++){
			cin>>x[i]>>y[i]>>f[i][1]>>f[i][2]>>f[i][3]>>f[i][4];
			if(!f[i][1])	lx=max(lx,x[i]);
			if(!f[i][2])	ry=min(ry,y[i]);
			if(!f[i][3])	rx=min(rx,x[i]);
			if(!f[i][4])	ly=max(ly,y[i]);
		}
		if(lx<=rx && ly<=ry)
			cout<<1<<" "<<lx<<" "<<ly<<endl;
		else
			cout<<0<<endl;
	}
	return 0;
}

Code(Java):

import java.util.Scanner;
public class Main {
	private static final int N = (int) 1e5;
	static int[] x = new int[N+10];
	static int[] y = new int[N+10];
	static int[][] f = new int[N+10][5];
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		int q = cin.nextInt();
		while(q-- >0){
			int n = cin.nextInt();
			int lx=-N,ly=-N,rx=N,ry=N;
			for(int i=1;i<=n;i++){
				x[i]=cin.nextInt();
				y[i]=cin.nextInt();
				f[i][1]=cin.nextInt();
				f[i][2]=cin.nextInt();
				f[i][3]=cin.nextInt();
				f[i][4]=cin.nextInt();
				if(f[i][1] == 0)	lx=Math.max(lx,x[i]);
				if(f[i][2] == 0)	ry=Math.min(ry,y[i]);
				if(f[i][3] == 0)	rx=Math.min(rx,x[i]);
				if(f[i][4] == 0)	ly=Math.max(ly,y[i]);
			}
			if(lx<=rx && ly<=ry)
				System.out.println(1 + " " + lx + " " + ly);
			else
				System.out.println(0);
		}
	}
}


D2. RGB Substring (hard version)(思维)

原题链接: https://codeforces.com/contest/1196/problem/D2


题意: 给出一个长度为 n,只含R,G,B字符的字符串 s 和一个长度 k,询问最少修改几个字符才能在字符串 s 中找到一个长度为 k 的"RGBRGBRGB…"的子串。

思路:

三个标准字符串:

RGBRGB…

GBRGBR…

BRGBRG…

分别对比标准字符串与所给字符串。如果某个字符相等的话,匹配度+1。最后找长度为 k 的连续子字符串匹配度的最大值,每种标准字符串均比较一次。k-该最大值即为修改的最小次数。

Code(C++):

#include <iostream>
using namespace std;
const int N=2e5+100;
string s1="RGB",s2="GBR",s3="BRG";
int sum[5][N];
int main(){
	int t;	cin>>t;
	while(t--){
		int n,k;
		string s;
		cin>>n>>k>>s;
		for(int i=0;i<=n;i++)
			sum[1][i]=sum[2][i]=sum[3][i]=0;
		for(int i=0;i<n;i++){
			sum[1][i+1]=sum[1][i];
			sum[2][i+1]=sum[2][i];
			sum[3][i+1]=sum[3][i];
			if(s[i]==s1[i%3])	sum[1][i+1]++;
			if(s[i]==s2[i%3])	sum[2][i+1]++;
			if(s[i]==s3[i%3])	sum[3][i+1]++;
		}
		int ans=0;
		for(int i=0;i+k<=n;i++)
			for(int j=1;j<=3;j++)
				ans=max(ans,sum[j][i+k]-sum[j][i]);
		cout<<k-ans<<endl;
	}
	return 0;
}

Code(Java):

import java.util.Scanner;
public class Main {
	private static final int N = (int) 2e5+100;
	static String s1="RGB";
	static String s2="GBR";
	static String s3="BRG";
	static int[][] sum = new int[5][N];
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		int q = cin.nextInt();
		while(q-- >0){
			int n = cin.nextInt();
			int k = cin.nextInt();
			String s = cin.next();
			for(int i=0;i<=n;i++)
				sum[1][i]=sum[2][i]=sum[3][i]=0;
			for(int i=0;i<n;i++){
				sum[1][i+1]=sum[1][i];
				sum[2][i+1]=sum[2][i];
				sum[3][i+1]=sum[3][i];
				if(s.charAt(i)==s1.charAt(i%3))	sum[1][i+1]++;
				if(s.charAt(i)==s2.charAt(i%3))	sum[2][i+1]++;
				if(s.charAt(i)==s3.charAt(i%3))	sum[3][i+1]++;
			}
			int ans=0;
			for(int i=0;i+k<=n;i++)
				for(int j=1;j<=3;j++)
					ans=Math.max(ans,sum[j][i+k]-sum[j][i]);
			System.out.println(k-ans);
		}
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值