Codeforces #441.Div.2

Posted 薛定谔的Submit

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Codeforces #441.Div.2相关的知识,希望对你有一定的参考价值。

A - Trip For Meal

题目大意:

  一个蹭饭的孩子有三个好朋友甲乙丙,他从甲的家里吃完饭后出发并在这三个人的家之间来回走。

  每到一个朋友家里,朋友都会请他吃顿饭,每次他吃完饭走之后,朋友又会立刻弄好一顿饭等他下次来吃。

  输入四行四个整数:n,a,b,c。n代表要吃几顿饭(从甲哪里出发时已经在甲家吃过一次)。a,b,c分别代表甲乙,甲丙以及乙丙家的距离。

  输出一行一个整数:代表这个孩子需要走的最短路程。

  数据范围:所有数据均 ∈[1,100]。

  样例:3 2 3 1 --> 3

     1 2 3 5 --> 0

解题思路:

  单纯的判断,首先判断最短的一条路是不是在a和b之间,如果是,就只需要在这条路上一直蹭吃的。

  若最短路是c,那么就先走一次a,b中的最短路,再在c上面徘徊。

A C 代码:

技术分享
 1 import java.util.*;
 2 
 3 public class Main{
 4 
 5     public static void main(String[] args){
 6         Scanner sc = new Scanner(System.in);
 7         while(sc.hasNext()){
 8             int n = sc.nextInt();
 9             int a = sc.nextInt();
10             int b = sc.nextInt();
11             int c = sc.nextInt();
12             if(n == 1){System.out.println("0");continue;}
13             if(a <= b && a <= c){
14                 System.out.println(a * (n - 1));
15             }
16             else if(b <= a && b <= c){
17                 System.out.println(b * (n - 1));
18             }
19             else if(c <= a && c <= b){
20                 int ans = Math.min(a,b) + (n - 2) * c;
21                 System.out.println(ans);
22             }
23         }
24     }
25 }
View Code

B - Divisiblity of Differences

题目大意:

  在一组数中找出若干个对另一个数取模相等的数。

  输入一行三个整数:n,k,m(2?≤?k?≤?n?≤?100?000, 1?≤?m?≤?100?000)。

  n代表接下来的数列中数的个数。k代表恰好在数列n中取出数字的个数。对m取模。

  输入一行n 个整数:代表数列n。数列中的数字 ∈[0,1e9]。

  输出一行"Yes"或"No":代表是否能取出这些数字。

  若第一行输出了"Yes",则再输出一行,代表被选出的数,数字用一个空格隔开,行末没有多余空格。

  样例输入:3 2 3      3 3 3      4 3 5

       1 8 4      1 8 4      2 7 7 7

  样例输出:Yes       No        Yes

       1 4                2 7 7

解题思路:

  在输入的时候将所有的数字处理,全部对m取模,并存放在一个个“桶”中记录次数。

  遍历这些“桶”,一但出现“桶”中的数字大于等于k,那么记录下这个模(modd),也就是“桶”的下标。

  然后遍历整个数组,如果n[i] % m == modd 那么输出n[i]。直到输出了k个数后,换行结束。

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 k = sc.nextInt();
 9             int m = sc.nextInt();
10             int mod[] = new int[m];
11             int num[] = new int[n];
12             int sum = 0;
13             int modd = 0;
14             for(int i = 0;i < n;i ++){
15                 num[i] = sc.nextInt();
16                 mod[num[i] % m] ++;
17             }
18             int flag = 1;
19             for(int i = 0;i < m;i ++){
20                 if(mod[i] >= k){
21                     modd = i;
22                     System.out.println("Yes");
23                     flag = 0;
24                     break;
25                 }
26             }
27             if(flag == 1){
28                 System.out.println("No");
29             }
30             else{
31                 int f = 0;
32                 for(int i = 0;i < n;i ++){
33                     if(num[i] % m == modd){
34                         sum ++;
35                         if(f == 0){System.out.print(num[i]);f ++;}
36                         else {System.out.print(" " + num[i]);}
37                     }
38                     if(sum == k){break;}
39                 }
40                 System.out.println();
41             }
42         }
43     }
44 }
View Code

C - Classroom Watch

题目大意:

  给一个正整数n,求出比他小的所有正整数并符合下面条件.

  若 x0 < n,且 x0 + (x0所有位数数字之和) == n,则 x0 符合条件。

  输入一行一个整数:n ∈ [1,1e9]。

  输出一行一个整数:k,代表符合条件的整数个数。

  若上一行输出的数字不是0,那么再输出k行k个整数,即从小到大排列的符合条件的数。

  样例输入:21      20

  样例输出:1       0

       15

解题思路:

  虽然n最多有10位,但是不难发现,所有位数数字和最多才90。

  题目中已经明确了一个公式: n = k + (所有位数数字和)。

  所以我们只需要循环 9 * (数字位数)次即可求出所有符合条件的数。

A C 代码:

技术分享
 1 import java.util.*;
 2 
 3 public class Main{
 4 
 5     static int check(String x){
 6         int s = 0;
 7         for(int i = 0;i < x.length();i ++){
 8             s = s + (x.charAt(i) - ‘0‘);
 9         }
10         return s;
11     }
12 
13     public static void main(String[] args){
14         Scanner sc = new Scanner(System.in);
15         while(sc.hasNext()){
16             int out[] = new int[100];
17             int index = 0;
18             String _in  = sc.nextLine();
19             int temp = 9 * _in.length();
20             int in = Integer.valueOf(_in);
21             for(int i = in - temp;i <= in;i ++){
22                 String t = String.valueOf(i);
23                 int ans = check(t);
24                 if(ans + i == in){
25                     out[index] = i;
26                     index ++;
27                 }
28             }
29             System.out.println(index);
30             for(int i = 0;i < index;i ++){
31                 System.out.println(out[i]);
32             }
33         }
34     }
35 }
View Code

D - Sorting the Coins

题目大意:

  有一排硬币,假设正面朝上为 O(大写o),背面朝上为 X。

  最开始硬币的状态都为 O 。

  然后有人给你捣乱,每次翻过来一个状态是 O 的硬币(之前翻过来的硬币不会再翻回去),直到将所有硬币全部翻过来。

  让你求出每次翻转后需要进行几次以下策略才能结束,策略数从0开始计算。

  最开始刚把所有硬币摆放好时(都是 O),也要进行策略。

  策略:

   如果这组硬币前边都是 O,后边都是 X(诸如OOOO或XXXX也算结束条件),那么结束。

   从左向右,如果当前(k)硬币状态是 X,并且下一个(k + 1)硬币状态是 O,那么就交换。

   交换过后从(k + 1)继续直到这行硬币被遍历结束。

   其他情况均保持不变。

   当所有的硬币归位后(即策略结束后),策略继续加一。

  输入一行一个整数:n ∈ [1,3e6],代表有n个硬币。

  输出一行n 个整数:每个整数代表这次翻过来的是几号硬币。

  样例输入:4            8

       1 3 4 2         6 8 3 4 7 2 1 5

  样例输出:1 2 3 2 1        1 2 2 3 4 3 4 5 1

解释样例:

  第一组:

   初始化:O O O O,无需进行策略,结束后策略次数加一,所以总共为 1。

   第一次:X O O O,进行一次策略,结束后策略次数加一,所以总共为 2。

   第二次:X O X O,进行两次策略,结束后策略次数加一,所以总共为 3。

   第三次:X O X X,进行一次策略,结束后策略次数加一,所以总共为 2。

   第四次:X X X X,无需进行策略,结束后策略次数加一,所以总共为 1。

解题思路:

  主要思想其实就是我们熟知的冒泡排序。将状态为X的硬币向后冒泡。

  模拟一下发现,每次翻转后进行的策略总次数就是将尾缀的所有X去掉后的X的数量。

  所以问题变成了如何计算尾缀的X。

超时代码(Java):

技术分享
 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 m[] = new int[n];
 9             int coins[] = new int[n];
10             for(int i = 0;i < n;i ++){
11                 m[i] = sc.nextInt();
12             }
13             System.out.print("1");
14             int tail = n;
15             int ans = 1;
16             for(int i = 0;i < n - 1;i ++){
17                 ans ++;
18                 coins[m[i] - 1] ++;
19                 while(coins[tail - 1] == 1){
20                     tail --;
21                     ans --;
22                 }
23                 System.out.print(" " + ans);
24             }
25             System.out.println(" 1");
26         }
27     }
28 }
View Code

 A C 代码(C/C++):

  其实两个代码是一样的,在我用Java交了3发超时之后,就用C写了一份一模一样的,然后直接过掉。

  这个题目好像并没有对Java提供额外的时间。

技术分享
 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     int n;
 6     while (scanf("%d",&n) != EOF)
 7     {
 8         int m[n] = {0};
 9         int coins[n] = {0};
10         for(int i = 0;i < n;i ++){
11             scanf("%d",&m[i]);
12         }
13         printf("1");
14         int tail = n;
15         int ans = 1;
16         for(int i = 0;i < n - 1;i ++){
17             ans ++;
18             coins[m[i] - 1] ++;
19             while(coins[tail - 1] == 1){
20                 tail --;
21                 ans --;
22             }
23             printf(" %d",ans);
24         }
25         printf(" 1\n");
26     }
27     return 0;
28 }
View Code

 










以上是关于Codeforces #441.Div.2的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces Round #441 Div. 2题解

[Codeforces] #441 div.2

Codeforces #441.Div.2

Codeforces Round #441 (Div. 2, by Moscow Team Olympiad)

Codeforces Round #441 (Div. 2, by Moscow Team Olympiad)

[Codeforces Round #522 (Div. 2, based on Technocup 2019 Elimination Round 3)][C. Playing Piano](代码片段