Codeforces Educational.Round.30

A - Chores

题目大意:

  有一个人有n份工作要完成,每份工作耗时不同,他有k次机会,能让一份工作只需要x个时间单位就能完成。求其最短工作时长。

  输入一行三个整数:n,k,x(1 <= k <= n <= 100,1 <= x <= 99)。

  输入一行n 个整数:代表每份工作的耗时,此行所有整数均 ∈ [2,100]。

  样例输入:4 2 2      5 2 1

       3 6 7 10     100 100 100 100 100

  样例输出:13        302

解题思路:

  单纯的sort一下即可,从后往前遍历,如果当前数字大于x,那么使用一次机会,机会没有了就用本来的速度。

A C 代码:

 1 import java.util.*;
 2 
 3 public class Main{
 4     public static void main(String[] args){
 5         Scanner sc = new Scanner(System.in);
 6         while(sc.hasNext()){
 7             int a = sc.nextInt();
 8             int b = sc.nextInt();
 9             int c = sc.nextInt();
10             int m[] = new int[a];
11             for(int i = 0;i < a;i ++){
12                 m[i] = sc.nextInt();
13             }
14             Arrays.sort(m);
15             int ans = 0;
16             for(int i = a - 1;i >= 0;i --){
17                 if(b != 0 && c < m[i]){
18                     ans = ans + c;
19                     b --;
20                 }
21                 else{
22                     ans = ans + m[i];
23                 }
24             }
25             System.out.println(ans);
26         }
27     }
28 }
View Code

B - Balanced Substring

题目大意:

  首先题目给你一个平衡串的定义,该串中0和1的数目相等即为平衡串。

  要求在给定一个只含有‘0’和‘1’的字符串中,

  求解其最大平衡子串的长度(没有则输出0)。

  输入一行一个整数:n,代表接下来字符串的长度(1 <= n <= 1e6)。

  输入一行一个字符串:s,代表该字符串。

  样例输入:8        3

       11010111     111

  样例输出:4        0

解题思路:

  声明 sum = 0 代表当前遇到的 0 1 的情况。

  遇0 sum -- ,遇1 sum ++ 。

  用一个长度为 n 的一维数组summ[]储存当前的sum。

  summ[]中,如果出现两个数字相等,那么就出现了平衡子串。

  该平衡子串的长度即为两个数字在summ[]里的下标之差。

  用mark[2 * n + 1][2]数组记录第一次出现某一个数字的下标和最后一次出现这个数字的下标。

  因为假设n == 5,那么所得的sum的可能 ∈[-5,5],共11单位的区间(即2 * 5 + 1)。

  所以在上文储存sum的值的时候,就应该令summ[] = sum + n。

  如此,sum = 0的时候就存到了summ[n],sum = -n的时候就存到了summ[0],sum = n的时候就存到了summ[2 * n]。

  最后遍历mark[][],找到最大的差就是最长平衡子串。

  该程序在测试时,无法准确判断如果sum == 0时的子串,比如 0110,101010,10001110等等。

  因为初始状态是sum == 0,但是并没有记录这个初始状态,比如0110。

  0110的summ[] = {-1,0,1,0}。在mark[n][]处储存的两个下标应该是1,3。

  但是实际上应该等于 3 - (-1) = 4,而非 3 - 1 = 2。(-1 为 初始sum == 0的状态)

  所以在遍历summ[]中,储存当sum == 0时的最后下标位置。

  在遍历mark[][]之后,继续进行一次比较,求出最大值即可。

  其实也可以在mark[n][0]处做手脚,让mark[n][0]永远等于 -1 即可。

A C 代码:

 1 import java.util.*;
 2 
 3 public class Main{
 4     public static void main(String[] args){
 5         Scanner sc = new Scanner(System.in);
 6         while(sc.hasNext()){
 7             int n = sc.nextInt();
 8             int mark[][] = new int[2 * n + 1][2];
 9             for(int i = 0;i < 2 * n + 1;i ++){
10                 mark[i][0] = -1;
11                 mark[i][1] = -1;
12             }
13             String enter = sc.nextLine();
14             String _in = sc.nextLine();
15             char in[] = _in.toCharArray();
16             int sum = 0;
17             int summ[] = new int[n];
18             int _max = 0;
19             for(int i = 0;i < n;i ++){
20                 if(in[i] == '0'){
21                     sum --;
22                     summ[i] = n + sum;
23                 }
24                 else{
25                     sum ++;
26                     summ[i] = n + sum;
27                 }
28                 if(summ[i] == n){_max = i + 1;}
29             }
30             for(int i = 0;i < n;i ++){
31                 if(mark[summ[i]][0] == -1){mark[summ[i]][0] = i;}
32                 mark[summ[i]][1] = i;
33             }
34             //for(int i = 0;i < 2 * n + 1;i ++){System.out.println(mark[i][0] + " " + mark[i][1]);}
35             //for(int i = 0;i < n;i ++){System.out.println(summ[i]);}
36             int maxx = -1;
37             for(int i = 0;i < 2 * n + 1;i ++){
38                 if(mark[i][1] - mark[i][0] > maxx){maxx = mark[i][1] - mark[i][0];}
39             }
40             if(_max > maxx){maxx = _max;}
41             System.out.println(maxx);
42         }
43     }
44 }
View Code

 

 

原文地址:https://www.cnblogs.com/love-fromAtoZ/p/7725420.html