130道基础OJ编程题之: 29 ~ 38 道

130道基础OJ编程题之: 29 ~ 38 道


OJ技巧

#include <stdio.h>

int main() {
    int a, b;
    while (scanf("%d %d", &a, &b) != EOF) { // 注意 while 处理多个 case
        // 64 位输出请用 printf("%lld") to 
        printf("%d\n", a + b);
    }
    return 0;
}
import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        // 注意 hasNext 和 hasNextLine 的区别
        while (in.hasNextInt()) { // 注意 while 处理多个 case
            int a = in.nextInt();
            int b = in.nextInt();
            System.out.println(a + b);
        }
    }
}

0. 昔日OJ编程题:

130道基础OJ编程题之: 1~7道_ChinaRainbowSea的博客-CSDN博客

130道基础OJ编程题之: 8~19 道_ChinaRainbowSea的博客-CSDN博客

130道基础OJ编程题之: 20~28_ChinaRainbowSea的博客-CSDN博客_编程


29. BC23 时间转换

时间转换_牛客题霸_牛客网 (nowcoder.com)

在这里插入图片描述


C语言实现:

思路: 已知定秒数 : 0 < seconds < 100000000, 的范围,int 类型足够存下,我们只需要通过秒数得到对应的 划分为对应的小时,秒,分钟:

  • 3661秒 / 60 / 60 = 小时
  • 3661 / 60 = 61 分钟,61 分钟 % 60 = 1 分钟,前 60 分钟转化为了 1小时,取模% 60得到剩下的 1 分钟
  • 3661 % 60 = 1 秒,前面被 60 取模尽都是 转换为了 小时,分钟,最后剩余的便是 秒了。
#include <stdio.h>

int main()
{
    int seconds = 0;
    scanf("%d",&seconds);
    
    int h = seconds/60/60;  // 小时
    int m = seconds/60%60;  // 分钟
    int s = seconds%60;     // 秒

    printf("%d %d %d",h,m,s);
    return 0;
}

方式二:

#include <stdio.h>

int main()
{
    int seconds = 0;
    scanf("%d",&seconds);
    
    int h = seconds/ 3600;  // 小时
    int m = (seconds - h*3600) / 60;  // 分钟
    int s = seconds - h*3600 - m * 60;     // 秒

    printf("%d %d %d",h,m,s);
    return 0;
}

Java实现:

方式一:

思路: 和上述C语言实现是一样的,这里就不重复讲述了

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int seconds = scanner.nextInt();

        int h = seconds / 60 / 60 ;  // 小时
        int m = seconds / 60 % 60 ;  // 分钟
        int s = seconds % 60 ;       // 秒

        System.out.println(h+" "+m+" "+s);
    }
}

方式二:

思路: 通过不断转换后的小时,分钟之间的减法得到对应的值

  • 3661 / 3660 = 1 小时;
  • 3661 - 1(小时) * 3600 = 61 (剩下秒数) / 60 = 分钟
  • 3661 - 得到的小时1*3600 - 得到的 1 分钟 * 60 = 剩余的秒数
import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        int seconds = scanner.nextInt();
        
        int h = seconds / 3600;             // 小时
        int m = (seconds - h * 3600) / 60 ; // 分钟
        int s = seconds - h * 3600 - m * 60  ; // 秒

        System.out.println(h+" "+m+" "+s);
    }
}

30. BC24 总成绩和平均分计算

总成绩和平均分计算_牛客题霸_牛客网 (nowcoder.com)

在这里插入图片描述


C语言实现:

方式一:

思路: 一次性将三个数值,全部输入完毕,注意 double 类型的输入输出格式是 %lf

#include <stdio.h>

int main()
{
    double gender1 = 0.0;
    double gender2 = 0.0;
    double gender3 = 0.0;

    scanf("%lf %lf %lf",&gender1,&gender2,&gender3);
    double sum = gender1+gender2+gender3;
    printf("%.2lf %.2lf",sum,sum/3);

    return 0;
}

方式二:

思路: 通过创建一个数组,用于存放输入的成绩的数值,同时计算求和,最后输出;

#include <stdio.h>

int main()
{
    double genders[3] = {0};
    double sum = 0.0;

    for(int i = 0; i < sizeof(genders)/(sizeof(int));i++) 
    {
        scanf("%lf",&genders[i]);
        sum += genders[i];
    }

    printf("%.2lf %.2lf",sum,sum/3);

    return 0;
}

Java实现:

思路: 通过创建double 类型的数组存放输入的数值,使用 new 的方式创建数组,可以指定数组的大小。在通过Java当中的 printf 的格式输出,需要注意的是Java当中的 printf 没有 %lf, %ld ,只有%d,%f

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        double[] genders = new double[3]; // 创建数组
        double sum = 0.0;
        for(int i = 0; i < genders.length;i++) {
            genders[i] = scanner.nextDouble();
            sum += genders[i];
        }

        System.out.printf("%.2f %.2f",sum,sum/3);
        /*
        注意在Java当中的 printf 对应的浮点数类型是 %f,没有%lf报错以及 整数类型只有 %d,没有%ld 报错*/
    }
}

方式二:

思路: 我们可以使用 String.format(Locale l,String format,Object... args) 的静态方法 替换 printf,格式化对应的字符串,locale 1 参数表示的是: 你想要表示的字符格式 %.2f/%.d 这样的,String format, 表示需要转换的字符串(如果传的是数值会自动转换为字符串),Object…args 可变参数,可以不传参数,但是不要传null,null引用。

在这里插入图片描述

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        double[] genders = new double[3]; // 创建数组
        double sum = 0.0;
        for(int i = 0; i < genders.length;i++) {
            genders[i] = scanner.nextDouble();
            sum += genders[i];
        }
        System.out.println(String.format("%.2f",sum)+" "+String.format("%.2f",sum/3));
        /*
        注意在Java当中的 printf 对应的浮点数类型是 %f,没有%lf报错以及 整数类型只有 %d,没有%ld 报错*/
    }
}

31. BC30 KiKi和酸奶

KiKi和酸奶_牛客题霸_牛客网 (nowcoder.com)
在这里插入图片描述


C语言实现:

思路: 注意是多组输入的方式 我们需要用上 while(scanf("%d %d %d",&n,&h,&m) != EOF) EOF 表示的文件结束标识,#define EOF (-1)

如果 h 分钟喝完一瓶酸奶,那么 m 分钟就可以喝 m /h 瓶酸奶,但是如果 m / h 有余数(m % h),就说明kiki正在喝一瓶酸奶,但是没有喝光,被喝的这一瓶酸奶也要算上,总的酸奶个数 n - 被喝的酸奶的个数 = 剩下酸奶的个数。

#include<stdio.h>

int main()
{
    int n = 0;
    int h = 0;
    int m = 0;
  

    while(scanf("%d %d %d",&n,&h,&m) != EOF) 
    {
        int sum = 0;
        if( m % h > 0 )  // 表示kiki正在喝酸奶,
        {
            sum = m / h + 1; // 加上kiki正在喝的这瓶酸奶
        }
        else            // 表示kiki不在喝酸奶
        {
            sum = m / h;
        }

        printf("%d\n",n - sum);
    }
    return 0;
}

方式二:

思路: 我们使用while(~scanf("%d %d %d",&n,&h,&m)) 替换掉while(scanf("%d %d %d",&n,&h,&m) != EOF) 的使用

补充:

说明: EOF 在 C++ 中表示的是 -1的意思,同时又是文件内容最后一个内容的结束标志。

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述


所以 EOF 的本质其实是 -1 ,而 ~ 表示的是取反的意思,while(~scanf(“%d %d %d”,&n,&h,&m))
表达的意思就是: 当scanf 返回的结果是 EOF 我们就将EOF(-1在C语言中非0 的表示真) 取反变成了 0(假),假跳出循环。

在这里插入图片描述

#include<stdio.h>

int main()
{
    int n = 0;
    int h = 0;
    int m = 0;
  

    while(~scanf("%d %d %d",&n,&h,&m)) 
    {
        int sum = 0;
        if( m % h > 0 )  // 表示kiki正在喝酸奶,
        {
            sum = m / h + 1; // 加上kiki正在喝的这瓶酸奶
        }
        else            // 表示kiki不在喝酸奶
        {
            sum = m / h;
        }

        printf("%d\n",n - sum);
    }
    return 0;
}

Java实现:

思路: 和C语言实现的方式一的思路是一样的,不同的是在Java当中多组输入整数 使用: while(scanner.hasNextInt()) 的方式.

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);

        while(scanner.hasNextInt()) {
            int n = scanner.nextInt();
            int h = scanner.nextInt();
            int m = scanner.nextInt();

            int sum = 0;
            if(m % h > 0 ) { // kiki正在喝酸奶,没有喝光
                sum = m / h +1;
            }
            else {
                sum = m / h;  // kiki没有在喝酸奶
            }

            System.out.println(n-sum);
        }
    }
}

32. BC31 发布信息

发布信息_牛客题霸_牛客网 (nowcoder.com)

在这里插入图片描述


C语言实现:

思路:

#include<stdio.h>

int main()
{
    printf("I lost my cellphone!\n");

    return 0;
}

java实现:

import java.util.*;

public class Main{
    public static void main(String[] args) {
        System.out.println("I lost my cellphone!");
    }
}

33. BC3 输出学生信息

输出学生信息_牛客题霸_牛客网 (nowcoder.com)

在这里插入图片描述

C语言实现:

思路: 注意空格的个数

#include<stdio.h>

int main(){
     
    printf("Name    Age    Gender\n");//注意四个空格 和换行
    printf("---------------------\n");
    printf("Jack    18     man\n");//注意五个空格 对齐
     
    return 0;
}

Java实现方法:

import java.util.*;

public class Main{
    public static void main(String[] args) {
        System.out.println("Name    Age    Gender");
        System.out.println("---------------------");
        System.out.println("Jack    18     man");
    }
}

34. BC33 计算平均成绩

计算平均成绩_牛客题霸_牛客网 (nowcoder.com)

在这里插入图片描述


C语言实现:

思路: 定义一个int数组,通过循环将 5 数值存入到数组中去了。

方式一:

#include<stdio.h>

int main()
{
    double sum = 0.0;
    int arr[5] = {0};

    for(int i = 0; i < 5; i++)
    {
        scanf("%d",&arr[i]);
        sum = arr[i] + sum;
    }
    
    printf("%.1lf",sum/5.0);
    
    return 0;
}

Java实现:

思路: 使用Java当中的printf 的格式输入,或者使用:String.format("%.1f",sum/5)

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int[] arrs = new int[5];
        double sum = 0.0;

        for(int i = 0; i < arrs.length;i++) {
            arrs[i] = scanner.nextInt();
            sum += arrs[i];
        }

        // System.out.printf("%.1f",sum/5); // 注意在java当中浮点数的格式输入是 %.f,没有%.2f,整型的格式是%.d没有 %.ld;
        // 或者使用
        System.out.println(String.format("%.1f",sum/5)); 
        // 注意同理:java当中的:%f,%d 的格式
    }
}

35. BC34 进制A+B

进制A+B_牛客题霸_牛客网 (nowcoder.com)

在这里插入图片描述


C语言实现:

思路: 十六进制Hexadecimal一般以0x开头,例如0xFF。八进制Octal,一般以0开头,例如07。

首先要理解十进制,十六进制,八进制只是一种数据的表示形式,不是数据的存储形式,它们的存储的都是二进制的。只是将二进制中的数据取出后的表示形式不同而已。具体详细说明,大家可以移步到: 数据是:如何在 ”内存“中的 ”存“ 和 ”取“ 的_ChinaRainbowSea的博客-CSDN博客

不同格式的数据的的输出在C语言中有不同的格式指定,比如:%x 是十六进制格式,%O 就是八进制格式。

不同进制得到数据存放都是补码,直接使用补码交给计算机。


#include<stdio.h>

int main()
{
    int num1 = 0;
    int num2 = 0; 
    scanf("%x %o",&num1,&num2);

    printf("%d\n",num1+num2);

    return 0;
}

Java实现:

思路: 我们先将数值,以字符串的类型读取,注意使用 nextLine(),和next的区别,nextLine()可以读取到空格,next不可以读取到空格,再使用 String.sqlit(" ") 的方法根据“ ”空格将读取到的字符串进行一个分组划分。将分组后的字符串存储到字符串数组中,再通过 Integer.parseInt()的方法将字符串的内容转为需要的进制的格式,十六进制,八进制。

在这里插入图片描述

通过 String.substring() 方法将去掉我们从键盘上读取到的 0x十六进制,0八进制的标志去了,通过获取到指定字符指定下标的内容。

在这里插入图片描述

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.nextLine(); // 注意nextLine和next的不同,next不可以读取到空格,nexttLine()可以读取到空格
        String[] sl = str.split(" "); // 将字符串的内容根据" "进行一个分割。并将分组后字符串内容返回到字符串数组中去
        
        // 去除0x,o使用
        int a = Integer.parseInt(sl[0].substring(2,sl[0].length()),16);
        int b = Integer.parseInt(sl[1].substring(1,sl[1].length()),8);
        System.out.println(a+b);

        // Integer int类型的包装类,parseInt(输出的数值,输出的格式)
        // substring(表示获取到对应下标之间的内容)

    }
}

36. BC37 网购

网购_牛客题霸_牛客网 (nowcoder.com)

在这里插入图片描述


C语言实现:

思路: 巧妙的设计变量,通过再通过 if 判断语句的方式,改变双11,双12 的变量的折扣,巧妙的使用 falg = 0 (优惠券)*50 后的值,0* 50 = 0;的方式。

注意我们最后的结果是保留两位小数’0.00’,以及商家不会回退钱的。

#include<stdio.h>

int main()
{
    double val = 0;
    int month = 0;
    int day = 0;
    int falg = 0;
    float discount = 1;

    scanf("%lf %d %d %d",&val,&month,&day,&falg);

    if(month == 11 && day == 11) // 双11
    {
        discount = 0.7;
        
    }

    if(month == 12 && day == 12) // 双12
    {
        discount = 0.8;
    }

    double sum = val*discount-falg*50; // 总和

    if(sum <= 0)
    {
        printf("0.00\n");
    }
    else
    {
        printf("%.2lf\n",sum);
    }

    return 0;
}

Java实现

思路: 和上述C语言实现的方式是一样的思路,需要明白的是,空格本身就可以最为分割不同输入的格式。

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        double val = scanner.nextDouble(); // 价格
        int month = scanner.nextInt();     // 月
        int day = scanner.nextInt();       // 天
        int falg = scanner.nextInt();      // 优惠券
        double discount = 0;               // 折扣
        double sum = 0;                    // 实际价格

        if(11==month && 11 == day) {
            discount = 0.7;
        }
        
        if(12==month && 12 == day) {
            discount = 0.8;
        }

        sum = val*discount-falg*50;

        if(sum <= 0) {
           // System.out.printf("0.00\n");  // %d,%f
           System.out.println("0.00");
        }
        else{
            // System.out.printf("%.2f",sum);
            // 或者使用
            System.out.println(String.format("%.2f",sum));
        }

    }
}

37.BC39 争夺前五名

争夺前五名_牛客题霸_牛客网 (nowcoder.com)

在这里插入图片描述


C语言实现:

思路: 这里由于是C语言不支持,arr[n] 数组大小变量的定义,所以我们一开始就将数组定义为题目中的最大同学的个数。通过for循环为数组多个数值赋值,再通过简单的冒泡排序将我们的同学的成绩进行一个降序(把数值大的变量放到数组的后面)的排序过程,排序好后,再遍历数组获取到前我五的数值内容,

注意冒泡排序的越界的的问题。下标访问的大小。

#include<stdio.h>

int main()
{
    int arr[50] = {0};
    int n = 0;
    scanf("%d",&n);

    for(int i = 0; i<n; i++) 
    {
        scanf("%d",&arr[i]);
    }

    // 冒泡排序,最后一个不用排序,升序
    for(int i = 0; i < n-1;i++) 
    {
        for(int j = 1; j < n-i;j++)  // 这里我们使用j = 1,防止n-i数组越界的访问.
        { // 小于的往后移动
            if(arr[j-1] < arr[j])
            {
                int temp = arr[j-1];
                arr[j-1] = arr[j];
                arr[j] = temp;
            }
        }
    }

    // 排序显示 前五个的成绩
    for(int i = 0; i < 5; i++)
    {
        printf("%d ",arr[i]);
    }

    return 0;
}

Java实现:

思路: 和上述C语言实现的方式是一样的,这就不多介绍了。

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int n = scanner.nextInt();
        int[] arrs = new int[n];
        for(int i = 0; i < arrs.length;i++){
            arrs[i] = scanner.nextInt();
        }

        // 冒泡排序,降序(数值小的放到后面)
        for(int i = 0; i < arrs.length-1;i++) {
            for(int j = 1; j < arrs.length-i;j++) { // 注意是从下标 1 开始的,
                if(arrs[j-1] < arrs[j]) { // 前面小的数值放后
                int temp = arrs[j];
                arrs[j] = arrs[j-1];
                arrs[j-1] = temp;
                }
            }
        }

        // 排序结束,取出前5个成绩
        for(int i = 0; i < 5; i++) {
            System.out.print(arrs[i]+" ");
        }
    }
}

38. BC40 竞选社长

竞选社长_牛客题霸_牛客网 (nowcoder.com)

在这里插入图片描述


C语言实现:

方式一:

思路: 我们通过创建定义一个字符数组,因为在C语言当中没有字符串类型,所以我们定义字符数组存储字符串,

再通过循环,将存入数组中的内容逐一取出,并判断是否等于 ‘A’/ ‘B’ 符合条件,计数,最后循环结束(注意需要结束的条件是 0 && 以及 EOF(文件结束标志)),判断各个的计数结果,输出内容。

#include<stdio.h>

int main()
{
    char arrs[100] = {0};
    gets(arrs);  // 读取字符串

    int i = 0;
    int countA = 0;
    int countB = 0;
    while(arrs[i]!=0 && arrs[i] !=EOF)
    {
        if('A' ==  arrs[i])
        {
            countA++;
        }
        
        if('B' == arrs[i])
        {
            countB++;  
        }

        i++;
    }

    if( countA > countB) 
    {
        printf("A\n");
    }
    else if(countA == countB) 
    {
        printf("E\n");
    }
    else 
    {
        printf("B\n");
    }
    return 0;
}

方式二:

思路: 配合使用循环使用上 getchar() 获取到对应的键盘上多个输入的值,每次读取到一个数值的内容再,进行一个判断和计数。最后通过计数的结果进行一个判断

#include<stdio.h>

int main()
{
   char c = 0;
   int countA = 0;
   int countB = 0;
   while( (c = getchar()) != '0')
   {
       if('A' == c)
       {
           countA++;

       }

       if('B' == c)
       {
           countB++;
       }

   } 

   if(countA < countB)
   {
       printf("B\n");
   }
   else if(countB == countA)
   {
       printf("E\n");
   }
   else
   {
       printf("A\n");
   }
   return 0;   
}

方式三:

思路: 只是定义一个变量对数据进行一个进行一个判断,通过变向的使用 ++自增,–自减的方式对,进行一个计数

#include<stdio.h>

int main()
{
    int flag = 0;
    char c = 0;

    while((c = getchar()) != '0' && c != EOF) 
    {
        if('A' == c) 
        {
            flag++;
        }

        if('B' == c)
        {
            flag--;
        }

    }

    if(flag > 0 )  // 表示 A 字符多了
    {
        printf("A\n");
    }
    else if(0 == flag)  // 表示 A 和 B 的数据同样多
    {
        printf("E\n");
    }
    else
    {
        printf("B\n");
    }

    return 0;
}

java实现:

方式一:

思路: 通过String.charAt() 的方法获取到指定字符串下标的字符内容,并进行一个判断,符合结果的进行一个计数。该方法的具体文档如下:

在这里插入图片描述

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.next();
        int countA = 0;
        int countB = 0;

        for(int i = 0; i < str.length();i++) {
            if(str.charAt(i) == 'A') { // 取出下标为i的字符串的字符,并判断
                countA++;
            }

            if('B' == str.charAt(i)) {
                countB++;
            }
        }

        if( countA > countB) {
            System.out.println("A");
        } else if(countA == countB) {
            System.out.println("E");
        } else {
            System.out.println("B");
        }
    }
}

方式二:

思路: 使用String.replace()将字符串中的内容替换成我们指定的内容

int countA = str.replace("B", "").length()-1; 将字符串的 B 替换成字符串 “ ” 没有的字符,那么剩下的不就全是 A 的字符了吗。这时候我们再求其字符串的长度,再额外减 - 1 ,去掉 包含的 0 字符。就是 A 在该字符串的个数了

int countB = str.replace("A","").length()-1 将字符串的 A 替换成没有的字符 “” ,那么剩下的不就全是 B 字符串了(包含 0 ),同样这个时候我们再求字符串的长度,再额外减 -1 ,去掉包含的 0 字符,就是 B 在该字符串的个数了。

该方法的具体文档内容如下:

在这里插入图片描述

import java.util.*;

public class Main{
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        String str = scanner.next();

        int countA = str.replace("B", "").length()-1;
        int countB = str.replace("A","").length()-1; // 字符串中的 A 替换成"" 空字符,剩余的不就是的B了吗,再求返回的字符串长度 -1 去掉 0 


        if( countA > countB){
            System.out.println("A");   
        } else if( countA == countB) {
            System.out.println("E");
        } else {
            System.out.println("B");
        }

    }
}

总结:

  1. C语言中的多个输入的值,EOF 表示文档的结束标志,while(scanf() != EOF) ,以及 while(~scanf())的意思(表示EOF(-1) 取反为 0 (假))
  2. Java当中的多组数据的输入 while (scanner.hasNextInt() 以及 next 与 nextLine 的区别: next()读取不到空格,nextLine()可以读取到空格
  3. 在Java当中使用 System.out.printf(%d,%f)以及 String.format("%d,%f",数值()转换为字符串) 表示格式输出,注意在Java当中是没有 %ld,%lf 的。
  4. C语言中的读取多个字符串 gets(arr)
  5. 在java 当中的 String.charAt() 获取到指定下标的字符串的内容,以及 str.replace("A","") 将字符串中的指定字符替换为指定的字符
  6. 注意冒泡排序,不要越界访问了。
  7. java当中的String.sqlit(" ") 对字符串的内容进行一划分,返回字符串数组。substring(2,string.length) 通过对应字符串下标开始,获取到指定长度的字符串。
  8. Integer.parseInt(String str,"%d/%f")的方法将字符串的内容转为需要的进制的格式,十六进制,八进制。

最后:

限于自身水平,其中存在的错误,希望大家可以多多指教,韩信点兵——多多益善,谢谢大家,后会有期,江湖再见 !!!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值