牛牛有一些排成一行的正方形。每个正方形已经被染成红色或者绿色。牛牛现在可以选择任意一个正方形然后用这两种颜色的任意一种进行染色,这个正方形的颜色将会被覆盖。牛牛的目标是在完成染色之后,每个红色R都比每个绿色G距离最左侧近。牛牛想知道他最少需要涂染几个正方形。
如样例所示: s = RGRGR
我们涂染之后变成RRRGG满足要求了,涂染的个数为2,没有比这个更好的涂染方案。
输入包括一个字符串s,字符串s长度length(1 ≤ length ≤ 50),其中只包括'R'或者'G',分别表示红色和绿色。
输出一个整数,表示牛牛最少需要涂染的正方形数量
RGRGR
2
s=input() res=[] for i in range(len(s)): res.append(s[:i].count('G')+s[i:].count('R')) print(min(res))
s = input() # 分别将[0,len(s)-1]作为最后一个red的位置,计算在这些分割点下染色的最小次数 print(min([s[:i].count('G') + s[i:].count('R') for i in range(len(s))]))而为了不用每次都遍历分割点左边的绿和右边的红,可以先用两个辅助数组记录一下,用到的时候直接查表
import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.IOException; public class Main { public static void main(String[] args) throws IOException { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); String str = br.readLine().trim(); int n = str.length(); int[] green = new int[n]; // green[i]表示0~i有多少个G int[] red = new int[n]; // red[i]表示i~n-1有多少个R green[0] = str.charAt(0) == 'G'? 1: 0; red[n - 1] = str.charAt(n - 1) == 'R'? 1: 0; for(int i = 1; i < n; i++){ green[i] = green[i - 1]; if(str.charAt(i) == 'G') green[i]++; } for(int i = n - 2; i >= 0; i--){ red[i] = red[i + 1]; if(str.charAt(i) == 'R') red[i]++; } int minCount = n; for(int i = -1; i < n - 1; i++) minCount = Math.min(minCount, (i > -1? green[i]: 0) + red[i + 1]); System.out.println(minCount); } }
//方法1:遍历一次数组,在当前位置为R时有可能两种情况,一种是把这个位置变成G,另一种是把前面的G全部变成R。 import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner scan = new Scanner(System.in); String str = scan.nextLine(); scan.close(); int gCount = 0, count = 0; for(int i=0; i<str.length(); i++) { if(str.charAt(i)=='G') { gCount++;//记录G的个数 } else {//如果当前字符是R count = Math.min(gCount, count+1); }//gCount表示把当前字符R前的所有G变成R,count表示当前字符R变成G } System.out.println(count); } } //方法2:用枚举,以每一个点为起点,左边的都是R,右边的都是G,记录每一次的次数,排序,得到最小的。 import java.util.Arrays; import java.util.Scanner; public class Main{ public static void main(String[] args) { Scanner scan = new Scanner(System.in); String str = scan.nextLine(); scan.close(); int[] count = new int[str.length()];//记录每一次枚举染色的次数 for(int i=0; i<str.length(); i++) { for(int j=0; j<i; j++) { if(str.charAt(j)=='G') { count[i]++;//若左边的是G,记录变成R的次数 } } for(int j=i+1; j<str.length(); j++) { if(str.charAt(j)=='R') { count[i]++;//若右边的是R,记录变成G的次数 } } } Arrays.sort(count); System.out.println(count[0]); } }
mystr = input()
mymin = Ry = Rcount = mystr.count('R')
GChangeCount = 0
for item in mystr:
if item == 'G':
GChangeCount +=1
else:
Rcount -=1
if GChangeCount>=Ry and Ry == Rcount:
mymin = Rcount
break
if Rcount+GChangeCount < mymin:
mymin = Rcount+GChangeCount
if Rcount == 0:
break
print(mymin)
#include<iostream> #include<stdio.h> #include<algorithm> #include<string> #include<vector> #include<math.h> using namespace std; int main(){ string s; cin >> s; int countR = count(s.begin(), s.end(), 'R'); int countG = count(s.begin(), s.end(), 'G'); int frontG = 0; int frontR = 0; int numColor = 0; int minColor = s.size() + 1; //遇到红且是最后一个连续红就试试前面改成红,后面改成绿 for(int i = 0; i < s.size(); ){ if(s[i] == 'R'){ while(i < s.size() && s[i] == 'R'){ frontR++; i++; } //前面的绿色(染红) + 后面的红色(染绿) numColor = frontG + (countR - frontR); minColor = min(minColor, numColor); } else{ frontG++; i++; } } cout << min(minColor, min(countR, countG)) << endl; }
#include<iostream>
#include<string>
using namespace std;
int main() {
string s;
cin >> s;
int length = s.size();
int ans = 50;
for (int i = 0; i < length; i++) {
int ans_temp = 0;
for (int j = 0; j < length; j++) {
if (s[j] == 'G' && j < i) ans_temp++;
if (s[j] == 'R' && j >= i) ans_temp++;
}
if (ans_temp <= ans) ans = ans_temp;
}
cout << ans << endl;
return 0;
}
AC率这么低,我以为什么题,结果做了以后发现是个小学阅读理解题(题意描述不明)。
import java.util.*; public class Main { private static final int N_MAX = 55; private static final int INT_MAX= 0x3f3f3f3f; public static void main(String[] args) { Scanner sc = new Scanner(System.in); char[] in = sc.next().toCharArray(); int[] counts = new int[N_MAX]; for (int i=1; i<=in.length; i++) { if (in[i-1] == 'R') { counts[i] = counts[i-1] + 1; } else { counts[i] = counts[i-1]; } } int ans = INT_MAX; for (int i=0; i<=in.length; i++) { int left = i - counts[i]; int right = counts[in.length] - counts[i]; ans = Math.min(left+right, ans); } System.out.println(ans); } }
import java.util.*; public class Main{ public static void main(String[] args){ try(Scanner in = new Scanner(System.in)){ System.out.println(helper(in.nextLine())); } } public static int helper(String s){ char[] a = s.toCharArray(); int min = Integer.MAX_VALUE; for(int i = 0;i < a.length;i++){ int s1 = 0,e1 = i,s2 = i,e2 = a.length,count = 0; while(s1 < e1){ if(a[s1] == 'G') count++; s1++; } while(s2 < e2){ if(a[s2] == 'R') count++; s2++; } min = Math.min(count,min); } return min; } }
#include<stdio.h> #include<string.h> #define min(a,b) a<b?a:b int main(){ char s[100]; scanf("%s",s); int i,j,Min=1e8,n=strlen(s); for(i=0;i<n;i++){ int cnt=0; for(j=0;j<i;j++) if(s[j]!='R') cnt++; for(j=i;j<n;j++) if(s[j]!='G') cnt++; Min=min(Min,cnt); } printf("%d\n",Min); }
我觉得我的方法简单,看大家很多是遍历所有可能的分界点做的,说一下我的方法,只需要遍历一次数组, 在当前位置为R时有可能两种情况,一种是吧这个位置编程G,另一种是吧前面的G全部变成R. 时间复杂度O(n),空间复杂度O(1) #include<bits/stdc++.h> using namespace std; int main() { std::ios::sync_with_stdio(false); string s; cin >> s; int len = s.size();// 获取字符串长度 int gCount = 0;// 字符串中G字母的个数 int count = 0; // 最小涂色次数 for(int i = 0; i < len;i++) { if(s[i] == 'G') { gCount++; }else { count = min(gCount, count + 1); } } cout << count << endl; return 0; }
const readline = require('readline') let count = 0 let str = '' let r = readline.createInterface({ input:process.stdin, output:process.stdout }) new Promise(function (resolve,reject) { r.on('line',str=>{ resolve(str) }) }).then(function (str) { for(let i = 0,temp = 0;i<str.length;i++){ if(str[i] === 'G'){ temp++ } else{ count = temp } } console.log(count) })