zoukankan      html  css  js  c++  java
  • 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
    ");
    26     }
    27     return 0;
    28 }
    View Code
  • 相关阅读:
    Python课程回顾(day26)网络编程
    Python课程回顾(day27)
    Python课程回顾(day25)
    Python课程回顾(day24)
    Python课程回顾(day23)
    Python课程回顾(day22)
    Python课程回顾(day21)
    Python课程回顾(day20)
    Python课程回顾(day19)
    hive小tips(各种解析)
  • 原文地址:https://www.cnblogs.com/love-fromAtoZ/p/7722938.html
Copyright © 2011-2022 走看看