PTA基础编程题目集编程题C、Java实现(完整且通过所有测试点)

PTA基础编程题目集编程题C、Java实现,记录一下遇到的问题,及时复习浏览一下。也希望帮助到一直没过某个测试点小伙伴。(有的两种语言代码太相似了,就没有用java再写一遍)


7-1 厘米换算英尺英寸

#include <stdio.h>
#include <math.h>
void Print_FootAndInch ( int N );

int main()
{
    int N;
    scanf("%d", &N);
    Print_FootAndInch(N);
    return 0;
}

void Print_FootAndInch ( int N )
{
   int foot = floor(N/30.48);
   float temp = (N-foot*30.48)*12;
   float inch = floor(temp/30.48);
   printf("%d %0.f", foot, inch);
}
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int foot = (int) Math.floor(N/30.48);
		float temp = (float) ((N-foot*30.48)*12);
		int inch = (int) Math.floor(temp/30.48);
		System.out.println(foot+" "+inch);
		in.close();
	}
}

7-2 然后是几点

#include <stdio.h>
void Print_Time ( int N, int pass);

int main()
{
    int N;
    int pass;

    scanf("%d", &N);
    scanf("%d", &pass);
    Print_Time(N, pass);
    return 0;
}


void Print_Time ( int N, int pass )
{
   int minute = N%100;
   int hour = N/100;
   int h = hour + pass/60;
   int m = minute + pass%60;
   if(m>=60)
    {
        h += m/60;
        m %= 60;
    }
    while(m < 0)
    {
        h--;
        m += 60;
    }
   printf("%01d%02d", h, m);
}
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int pass = in.nextInt();
		
		int minute = N%100;
		int hour = N/100;
		int h = hour + pass/60;
		int m = minute + pass%60;
		if(m>=60){
			h += m/60;
		    m %= 60;
		}
		while(m < 0){
		    h--;
		    m += 60;
		}
		System.out.print(String.format("%01d", h));
		System.out.print(String.format("%02d", m));
		
		in.close();
	}
}

7-3 逆序的三位数

#include <stdio.h>
#include <stdlib.h>

int main()
{
    char* str = (char*)malloc(sizeof(char)*3);
    scanf("%s",str);

    if(str[2] == '0')
    {
        if(str[1] == '0')
        {
            printf("%c", str[0]);
        }else
        {
            printf("%c", str[1]);
            printf("%c", str[0]);
        }
    }else
    {
        printf("%c", str[2]);
        printf("%c", str[1]);
        printf("%c", str[0]);
    }

    return 0;
}
public class B73 {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		String str = in.next();
		
		if(str.charAt(2) == '0')
	    {
	        if(str.charAt(1) == '0')
	        {
	            System.out.print(str.charAt(0));
	        }else
	        {
	        	System.out.print(str.charAt(1));
	        	System.out.print(str.charAt(0));
	        }
	    }else
	    {
	    	System.out.print(str.charAt(2));
	    	System.out.print(str.charAt(1));
	    	System.out.print(str.charAt(0));
	    }

	}
}

7-4 BCD解密

用一个字节来表达两位十进制的数,每四个比特表示一位。一个字节8bit,一个bit表示0或1。BCD数的十六进制是0x12,它表达的就是十进制的12。0x12按照十六进制%x的输出就是12,理解为BCD数的十进制就是去掉十六进制前面那个符号比较合理 (我开始以为无论十六进制或者是十进制都是从1100得到的,但是0x87转化为二进制1000,0111;87转化为二进制0101,0111不对呀)

但是小明没学过BCD,把所有的BCD数都当作二进制数转换成十进制输出了(就是说0x12=16*1+2=18)

现在,你的程序要读入这个错误的十进制数(18),然后输出正确的十进制数(12)。就是把小明的操作逆过去,十进制换为十六进制。

#include <stdio.h>
int main()
{
  int a;
  scanf("%d",&a);
  printf("%0x",a);
  return 0;
}
System.out.println("二进制输出"+Integer.toBinaryString(b));
System.out.println("八进制输出"+Integer.toOctalString(b));
System.out.println("十六进制输出"+Integer.toHexString(b));

7-5 表格输出

#include<stdio.h>
int main()
{
 printf("------------------------------------\n");
 printf("Province      Area(km2)   Pop.(10K)\n");
 printf("------------------------------------\n");
 printf("Anhui         139600.00   6461.00\n");
 printf("Beijing        16410.54   1180.70\n");
 printf("Chongqing      82400.00   3144.23\n");
 printf("Shanghai        6340.50   1360.26\n");
 printf("Zhejiang      101800.00   4894.00\n");
 printf("------------------------------------\n");
 return 0;
}

7-6 混合类型数据格式化输入

scanf的读入格式是严格对应的
两种读取方式还是有点不同

#include<stdio.h>
int main()
{
 float num_float1;
 int num_int;
 char num_char;
 float num_float2;
 scanf("%f %d %c %f",&num_float1, &num_int, &num_char, &num_float2);
 printf("%c %d %0.2f %0.2f",num_char, num_int, num_float1, num_float2);
 return 0;
}
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		float N1 = in.nextFloat();
		int Int = in.nextInt();
		String c = in.next(); //读取空格之前的
		float N2 = in.nextFloat();
		
		System.out.println(String.format("%s %d %.2f %.2f", c,Int,N1,N2));
	}
}

7-7 12-24小时制

#include<stdio.h>
int main()
{
 int hour;
 int minute;
 scanf("%d:%d",&hour, &minute);
 if(hour > 12)
 {
     hour -= 12;
     printf("%d:%d PM", hour, minute);
 }else if(hour < 12)
 {
     printf("%d:%d AM", hour, minute);
 }else
 {
     printf("12:%d PM", minute);
 }
 return 0;
}
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		String N = in.next();
		in.close();

		Integer hour = Integer.parseInt(N.split(":")[0]);
		Integer minute = Integer.parseInt(N.split(":")[1]);
		
		if(hour > 12)
		 {
		     hour -= 12;
		     System.out.printf("%d:%d PM", hour, minute);
		 }else if(hour < 12)
		 {
			 System.out.printf("%d:%d AM", hour, minute);
		 }else
		 {
			 System.out.printf("12:%d PM", minute);
		 }
	}
}

7-8 超速判断

#include<stdio.h>
int main()
{
 int speed;
 scanf("%d",&speed);
 if(speed > 60)
 {
     printf("Speed: %d - Speeding", speed);
 }else
 {
     printf("Speed: %d - OK", speed);
 }
 return 0;
}

7-9 用天平找小球

#include<stdio.h>
int main()
{
 int b1, b2, b3;
 scanf("%d %d %d",&b1, &b2, &b3);
 if(b1 == b2)
 {
     printf("C");
     return 0;
 }
 if(b1 == b3)
 {
     printf("B");
     return 0;
 }
 printf("A");
 return 0;
}

7-10 计算工资

#include<stdio.h>
int main()
{
 int year;
 float time;
 scanf("%d %f",&year, &time);
 if(year >= 5)
 {
     if(time > 40)
     {
         printf("%0.2f",2000+(time-40)*1.5*50);
         return 0;
     }
     printf("%.2f",time*50);
     return 0;
 }else
 {
     if(time > 40)
     {
         printf("%0.2f",1200+(time-40)*1.5*30);
         return 0;
     }
     printf("%.2f",time*30);
     return 0;
 }
 return 0;
}

7-11 分段计算居民水费

#include<stdio.h>
int main()
{
 float water;
 scanf("%f",&water);
 if(water > 15)
 {
     printf("%.2f",water*2.5-17.5);
     return 0;
 }
 printf("%.2f",water*4/3);
 return 0;
}

7-12 两个数的简单计算器

#include<stdio.h>
int main()
{
 int n1;
 char c;
 int n2;
 scanf("%d %c %d",&n1, &c, &n2);
 if(c == '+')
 {
     printf("%d",n1+n2);
 }else if(c == '-')
 {
     printf("%d",n1-n2);
 }else if(c == '*')
 {
     printf("%d",n1*n2);
 }else if(c == '/')
 {
     printf("%d",n1/n2);
 }else if(c == '%')
 {
     printf("%d",n1%n2);
 }else
 {
     printf("ERROR");
 }
 return 0;
}

7-13 日K蜡烛图

#include<stdio.h>
int main()
{
 float open, high, low, close;
 scanf("%f %f %f %f",&open, &high, &low, &close);
 if(close < open)
 {
     printf("BW-Solid");
 }else if(close > open)
 {
     printf("R-Hollow");
 }else
 {
     printf("R-Cross");
 }

 int type = 0;
 if(low < close && low < open)
 {
     type = 1;
 }
 if(high > open && high > close)
 {
     type += 2;
 }

 if(type == 1)
 {
     printf(" with Lower Shadow");
 }else if(type == 2)
 {
     printf(" with Upper Shadow");
 }else if(type == 3)
 {
     printf(" with Lower Shadow and Upper Shadow");
 }
 return 0;
}

7-14 求整数段和

#include<stdio.h>
int main()
{
 int a,b;
 scanf("%d %d",&a, &b);
 int i = 0;
 int sum = (a+b)*(b-a+1)/2;

 while(a <= b)
 {
    for(i=0; i<5; i++)
    {
        printf("%5d", a);
        a++;
        if(a > b)
        {
            break;
        }
    }
    printf("\n");
 }
 printf("Sum = %d", sum);
 return 0;
}

7-15 计算圆周率

#include <stdio.h>
int main()
{
  float sum = 0;
  float value = 1;
  int i = 1;
  float threshold;
  scanf("%f",&threshold);
  do
  {
      sum += value;
      value = value*i/(i*2+1);
      i++;
  }while(value > threshold);
  sum += value;
  printf("%.6f", sum*2);
  return 0;
}

7-16 求符合给定条件的整数集

#include <stdio.h>
int main()
{
  int begin;
  scanf("%d",&begin);
  int a[4];
  for(int j=0; j<4; j++)
  {
      a[j] = begin;
      ++begin;
  }

  int j = 0;
  int k = 0;
  int flag = 1;
  for(int i=0; i<4; i++)
  {
      j = 0;
      while(j < 4)
      {
          if(j == i)
          {
              j++;
          }
          if(j >= 4)
          {
              break;
          }
          k = 0;
          while(k < 4)
          {
              while(k == j || k == i)
              {
                  k++;
              }
              if(k >= 4)
              {
                  break;
              }
              if(!flag)
              {
                  printf(" ");
              }
              flag = 0;
              printf("%d", a[i]);
              printf("%d", a[j]);
              printf("%d", a[k]);
              k++;
          }
        j++;
      }
      if(i != 3)
      {
          printf("\n");
          flag = 1;
      }
  }
  return 0;
}

写复杂了,有更简单的

 for(i=n;i<=n+3;i++)
    for(j=n;j<=n+3;j++)
       for(k=n;k<=n+3;k++)
       if(i!=j&&j!=k&&i!=k){
        count++;
        if(count%6==0)
        printf("%d%d%d\n",i,j,k);
        else
        printf("%d%d%d ",i,j,k);
       }

7-17 爬动的蠕虫

#include <stdio.h>
int main()
{
  int n, u, d;
  scanf("%d %d %d",&n, &u, &d);
  int sum = 0;
  int time = 0;
  while(sum < n)
  {
      sum += u;
      time++;
      if(sum >= n)
      {
          break;
      }
      sum -= d;
      time++;
  }
  printf("%d", time);
  return 0;
}

7-18 二分法求多项式单根

浮点数为0的判断fabs(value) >= 1e-6,否则陷入死循环

#include <stdio.h>
#include<math.h>
float a3, a2, a1, a0;

float count(float x)
{
    return a3*pow(x,3)+a2*pow(x,2)+a1*x+a0;
}

void findZero(float negative, float positive)
{
    float mid = (negative+positive)/2;
    float value = count(mid);
    //printf("mid: %.2f ", mid);
    //printf(" %.2f\n", value);
    //int counts = 0;
    while(fabs(value) >= 1e-6)
    {
        if(value > 0)
        {
            positive = mid;
            mid = (negative + positive)/2;
        }
        else
        {
            negative = mid;
            mid = (negative + positive)/2;
        }
        value = count(mid);
        //printf("mid: %.2f ", mid);
        //printf(" %.2f\n", value);
        //counts++;
    }
    printf("%.2f", mid);
}

int main()
{
    scanf("%f %f %f %f",&a3, &a2, &a1, &a0);
    float a, b;
    scanf("%f %f", &a, &b);
    float value2 = (a+b)/2;
    float value = count((a+b)/2);
    float acount = count(a);
    float bcount = count(b);
    //printf("%.2f %.2f %.2f\n", acount, bcount, value);

    if(acount == 0)
    {
        printf("%.2f", a);
    }
    else if(bcount == 0)
    {
        printf("%.2f", b);
    }
    else if(acount > 0 && value < 0)
    {
        findZero(value2, a);
    }
    else if(acount < 0 && value > 0)
    {
        findZero(a, value2);
    }
    else if(bcount > 0 && value < 0)
    {
        findZero(value2, b);
    }
    else
    {
        findZero(b, value2);
    }
    return 0;
}

7-19 支票面额

#include <stdio.h>

int main()
{
    int n, f, y;
    scanf("%d",&n);
    for(f=0; f<=99; f++)
    {
        for(y=0; y<=99; y++)
        {
            if(200*y+2*f+n == 100*f+y)
            {
                printf("%d.%d", y, f);
                return 0;
            }
        }
    }
    printf("No Solution");
    return 0;
}

7-20 打印九九口诀表

#include <stdio.h>

int main()
{
    int n;
    scanf("%d",&n);
    for(int r=1; r<=n; r++)
    {
        for(int l=1; l<=r; l++)
        {
                printf("%d*%d=%-4d", l, r, l*r);
        }
        printf("\n");
    }
    return 0;
}

Java也可以这样输出

System.out.printf("%5d:%-5d AM", hour, minute);

7-21 求特殊方程的正整数解

#include <stdio.h>

int main()
{
    int n;
    scanf("%d",&n);
    int put = 1;
    for(int r=1; r<=100; r++)
    {
        for(int l=1; l<=100; l++)
        {
            if(r*r+l*l == n && r<=l)
            {
                printf("%d %d\n", r, l);
                put = 0;
                break;
            }
        }
    }
    if(put)
    {
        printf("No Solution");
    }
    return 0;
}

7–22 龟兔赛跑

#include <stdio.h>

int main()
{
    int t;
    scanf("%d", &t);
    if(t <= 10)
    {
        printf("^_^ %d", 9*t);
        return 0;
    }
    t -= 10;
    int tl = 30;
    int rl = 90;
    while(t > 0)
    {
        if(rl > tl && t>30)
        {
            tl += 90;
            t -= 30;
        }
        else if(rl > tl && t<=30)
        {
            tl += 3*t;
            t = 0;
        }
        else if(rl <= tl && t>=10)
        {
            tl += 30;
            rl += 90;
            t -= 10;
        }
        else if(rl <= tl && t<10)
        {
            tl += t*3;
            rl += t*9;
            t = 0;
        }
    }
    if(tl > rl)
    {
        printf("@_@ %d", tl);
    }
    else if(tl < rl)
    {
        printf("^_^ %d", rl);
    }
    else
    {
        printf("-_- %d", tl);
    }
    return 0;
}

7-23 币值转换

C、Java的除法是截断的

#include <stdio.h>

void OutPut( char *output, int count)
{
    //处于末尾的0都要省略掉,跳过数组前面的a
    int end = 0;
    while(output[end] == 'a')
    {
        end += 2;
    }
    if(end != 0)
    {
        //要把最后那个的单位留下
        end -= 1;
    }

    char before;
    for(int i=count-2; i>=end; i--)
    {
        //0的后面不跟单位;前一个输出是a,后面接连的a也不能输出2,0008;
        if((output[i+1] == 'a') || (before == 'a' && output[i] == 'a'))
        {
            continue;
        }
        printf("%c", output[i]);
        before = output[i];
    }
}

int main()
{
    int t;
    scanf("%d", &t);
    if(t == 0)
    {
        printf("a");
        return 0;
    }

    char unit[8] = {'S', 'B', 'Q', 'W', 'S', 'B', 'Q','Y'};
    int u = 0;
    int tmp;
    char output[18];
    int count = 0;

    while(t > 0)
    {
        tmp = t%10;
        t /= 10;
        output[count++] = 97+tmp;
        output[count++] = unit[u++]; //会多一个单位,输出的时候跳过
    }

    //200080W的单位要带上,所以以万为单位分开输出
    if(count <= 8)
    {
        //没有上万
        OutPut(output, count);
    }
    else
    {
        char behind[count-8];
        for(int i=8; i<count; i++)
        {
            behind[i-8] = output[i];
        }
        OutPut(behind, count-8);

        printf("W");

        char ahead[8];
        for(int i=0; i<8; i++)
        {
            ahead[i] = output[i];
        }
        OutPut(ahead, 8);
    }
    return 0;
}

7-24 约分最简分式

如果用Java则读入一个字符串在转换为数字Integer.parseInt(N.split("/")[0]);

#include <stdio.h>

int commomDivisor(int s, int b)
{
    int tmp1, tmp2;
    if(s<b)
    {
        tmp1 = s;
        s = b;
        b = tmp1;
    }
    while(b != 0)
    {

        tmp2 = b;
        b = s%b;
        s = tmp2;

    }
    return s;
}

int main()
{
    int a, b;
    scanf("%d/%d", &a, &b);

    int divisor = commomDivisor(a, b);
    a /= divisor;
    b /= divisor;
    printf("%d/%d", a, b);
    return 0;
}

7-25 念数字

这道题想偷懒用个栈,就用的cpp

#include <iostream>
#include<stack>
#include<stdlib.h>
using namespace std;

int main ()
{
    int t, tmp;
    stack <int>stk;
    scanf("%d", &t);
    if(t < 0)
    {
        printf("fu ");
        t = abs(t);
    }
    if(t == 0)
    {
        printf("ling");
        return 0;
    }
    char const *name[10] = {"ling", "yi", "er", "san", "si", "wu", "liu", "qi", "ba", "jiu"};

    int c = 0;
    while(t > 0)
    {
        tmp = t%10;
        stk.push(tmp);
        c++;
        t /= 10;
    }

    while(c>1)
    {
        //printf(" %s", name[stk.top()]);
        cout << name[stk.top()]<< " " ;
        stk.pop();
        c--;
    }
    cout << name[stk.top()];
    return 0;
}

7-26 单词长度

因为结尾有空格干扰,不知道最后计数的是单词还是空格,所以少的一个空格由第一个输出的省略掉。(或者换一种计数方式,不是遇到空格清零,而是这个数不是空格而上一个数是空格清零)

#include <stdio.h>

int main()
{
    char c = ' ';
    int sum = 0;
    int flag = 0;//排除空句子和前面的空格
    int first = 1;//第一个不输出空格
    while(c != '.')
    {
        scanf("%c", &c);
        if(c != ' ')
        {
            flag = 1;
        }

        if(c == ' ' && flag)
        {
            if(first)
            {
                printf("%d", sum);
                sum = 0;
                first = 0;
            }
            //排除句子中间出现的空格
            if(sum != 0 && !first)
            {
                printf(" %d", sum);
                sum = 0;
            }
        }
        else if(c == '.')
        {
            //排除结尾的空格
            //空句子什么都不输出
            if(sum != 0)
            {
                if(first)
                {
                    //一个单词的情况
                   printf("%d", sum);
                   break;
                }
                printf(" %d", sum);
            }
            break;
        }
        else if(c != ' ')
        {
            sum++;
        }
    }
    return 0;
}

用Java写过测试点方便点,但是其实不是特别严谨。C语言好像也能这个思路解题strlen(str)返回单个字符串长度C语言字符串分割

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		String N = in.nextLine();
		//读一行的数据,如果在句号后面还有单词拿这种方法就不行

		String str[] = N.split(" |\\.");
		//题目说这里的单词与语言无关,可以包括各种符号,如果句子里有.也会不对
		
		boolean first = true;
		for (String retval: str){
            if(retval.length() != 0) {
            	
            	if(first) {
            		System.out.print(retval.length());
            		first = false;
            		continue;
            	}
            	System.out.print(" "+retval.length());
            }
        }
	}
}

7-27 冒泡法排序

import java.util.Arrays;
import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int K = in.nextInt();
		int[] arr = new int[N];
		for (int i = 0; i < N; i++) {
			arr[i] = in.nextInt();
		}
		in.close();

		int tmp = 0;
		while (K > 0) {
			for (int i = 0; i < N - 1; i++) {
				if (arr[i] > arr[i + 1]) {
					tmp = arr[i];
					arr[i] = arr[i + 1];
					arr[i + 1] = tmp;
				}
			}
			K--;
		}
		
//		System.out.println(Arrays.toString(arr));
		for (int i = 0; i < N - 1; i++) {
			System.out.printf("%d ",arr[i]);
		}
		System.out.printf("%d",arr[N-1]);
	}
}

7-28 猴子选大王

#include <stdio.h>
int main()
{
    int sum = 0; //报数为3时淘汰猴子,并且sum变为0
    int n;
    scanf("%d", &n);
    int m = n; //记录还剩多少monkey
    int p = 0; //数组指针
    //int a[n] = {0};不能这样初始化
    int a[n];
    for(int i=0; i<n; i++)
    {
        a[i] = 1;
    }

    while(m != 1)
    {
        if(a[p] != 0)
        {
            //当前不是淘汰的猴子才能报数
            sum++;
        }
        if(sum == 3)
        {
            //淘汰一只猴子
            a[p] = 0;
            m--;
            sum = 0;
        }
        p++;
        if(p == n)
        {
            //轮一圈后返回下一圈
            p = 0;
        }
    }

    for(int i=0; i<n; i++)
    {
        if(a[i] == 1)
            printf("%d", i+1);
    }
    return 0;
}

7-29 删除字符串中的子串

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		String N = in.nextLine();
		String mark = in.nextLine();
		in.close();

		String str[] = N.split(mark);
		
		while(str.length != 1) {
			N = "";
			for (String retval: str){
				N = N.concat(retval);
			}
			str = N.split(mark);
		}
		
		for (String s: str){
			System.out.print(s);
		}
	}
}

感觉挨着去比真的麻烦,按照同样的思路,C语言的版本。scanf函数不能接收带空格的字符串,sanf把空格当成结束符。gets()函数从标准输入(键盘)读入一行数据,所谓读取一行,就是遇到换行符就返回。但是不要puts()字符串,会自动带回车,可能被判格式不正确。

#include<stdio.h>
#include<string.h>

int main()
{
    char str[81],mark[81],temp[81];
    char *p;

    gets(str);
    gets(mark);

    while((p=strstr(str,mark)) != NULL)
    {
        //在字符串str中查找第一次出现字符串mark的位置,不包含终止符 '\0'。
        strcpy(temp, p+strlen(mark));
        //把mark所指向的字符串复制到temp, 相当于去覆盖掉了
        *p='\0'; 
        //将str后面的部分都删除掉了
        strcat(str, temp);
        //把tmp所指向的字符串追加到str所指向的字符串的结尾。
    }
    printf("%s", str);
    return 0;
}

7-30 字符串的冒泡排序

比较字符串大小的函数,爱了爱了str.compareTo(str2)

import java.util.Scanner;

public class Main {
	
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int N = in.nextInt();
		int K = in.nextInt();
		String[] arr = new String[N];
		for (int i = 0; i < N; i++) {
			arr[i] = in.next();
		}
		in.close();

		String tmp = "";
		while (K > 0) {
			for (int i = 0; i < N - 1; i++) {
				if (arr[i].compareTo(arr[i + 1]) > 0) {
					tmp = arr[i];
					arr[i] = arr[i + 1];
					arr[i + 1] = tmp;
				}
			}
			K--;
		}
		
		for (int i = 0; i < N; i++) {
			System.out.println(arr[i]);
		}
	}
}

C语言使用stricmp函数编译不通过,使用strcmp才行。
strcmp比较区分字母大小写 相当是比较的时候纯粹按照ascii码值来比较而stricmp是不区分字母的大小写的。而且字符数组的指针不能直接=赋值。如果用gets接收的话,记得在前面加一个getchar。

#include<stdio.h>
#include<string.h>

int main()
{
    int N, K;
    scanf("%d %d", &N, &K);
    char arr[N][11]; //char *arr[N]
    for(int i=0; i<N; i++)
    {
        scanf("%s",arr[i]);
    }

    char tmp[11];
    while (K > 0)
    {
        for (int i = 0; i < N-1; i++)
        {
            if (strcmp(arr[i], arr[i + 1]) > 0)
            {
                strcpy(tmp, arr[i]);
                strcpy(arr[i], arr[i + 1]);
                strcpy(arr[i + 1], tmp);
            }
        }
        K--;
    }

    for (int i = 0; i < N-1; i++)
    {
        printf("%s\n", arr[i]);
    }
    printf("%s", arr[N-1]);
    return 0;
}

7-31 字符串循环左移

System.arraycopy(原数组,起始索引,目标数组,目标数组起始下标,要复制的个数);

import java.util.Scanner;

public class Main {

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		String line = in.nextLine();
		int N = in.nextInt();
		in.close();
		
		char[] c =line.toCharArray();
		int L = c.length;
		char[] c2 = new char[L];

		if (N % L == 0) {
			for (char i : c) {
				System.out.print(i);
			}
		} else {
			N %= L;
			System.arraycopy(c, N, c2, 0, c.length - N);
			System.arraycopy(c, 0, c2, c.length - N, N);

			for (char i : c2) {
				System.out.print(i);
			}
		}
	}
}
#include<stdio.h>
#include<string.h>

int main()
{
    char str[101],temp[101];
    char *p;

    int n;
    gets(str);
    scanf("%d", &n);
    n %= strlen(str);
    p = str;
    strcpy(temp, p+n);
    strncat(temp, str, n);
    //把 str所指向的字符串追加到 temp所指向的字符串的结尾,直到 n 字符长度为止。
    printf("%s", temp);
    return 0;
}

7-32 说反话-加强版

因为用Java实现的过程非常曲折,所以另外写了一篇博客,里面包含java、c、cpp的通过代码,欢迎交流。i’m so vegetables
在这里插入图片描述

7-33 有理数加法

#include<stdio.h>

long commomDivisor(long s, long b)
{
    long tmp1, tmp2;
    if(s<b)
    {
        tmp1 = s;
        s = b;
        b = tmp1;
    }
    while(b != 0)
    {

        tmp2 = b;
        b = s%b;
        s = tmp2;
    }
    return s;
}

int main()
{
    int a1, b1, a2, b2;
    scanf("%d/%d %d/%d", &a1, &b1, &a2, &b2);
    long top = a1*b2 + a2*b1; //因为没有约分就去乘法了,怕数据大
    long bottom = b1*b2;

    long divisor = commomDivisor(top, bottom);

    top /= divisor;
    bottom /= divisor;

    if(bottom == 1)
    {
        printf("%d", (int)top);
    }
    else
    {
        printf("%d/%d", (int)top, (int)bottom);
    }
    return 0;
}

7-34 通讯录的录入与显示

这份写的比我好,学习一下,就贴了过来。特别小心一个问题,可能只考虑超出通讯录数量的正数,没考虑负数。

#include <stdio.h>
#include <string.h>

struct contacts
{
    char name[11];  //字符串结尾有\0,长度需加1,下同
    char birth[11];
    char gender;
    char fphone[17]; //固定电话fixed phone
    char mphone[17]; //移动电话mobile phone
};

void input();
void output();

int main()
{
    int n;
    scanf("%d", &n);
    struct contacts t[n];  //定义结构体数组,数组中每个元素都是一个结构体
    input(t, n);
    output(t, n);

    return 0;
}

void input(struct contacts p[], int n)
{
    int i;
    for(i = 0; i < n; i++)
    {
        scanf("%s %s %c %s %s", p[i].name, p[i].birth,
              &p[i].gender, p[i].fphone, p[i].mphone); //gender不是数组,别忘了&
    }
}

void output(struct contacts q[], int n)
{
    int m;
    scanf("%d", &m);
    int a[m]; //用一个数组记录要查找的记录编号

    int j;
    for(j = 0; j < m; j++)
    {
        scanf("%d", &a[j]);
    }

    for(j = 0; j < m-1; j++)
    {
        if(a[j] >=0 && a[j] < n)
        {
            printf("%s %s %s %c %s\n", q[a[j]].name, q[a[j]].fphone,
                   q[a[j]].mphone, q[a[j]].gender, q[a[j]].birth);
        }
        else
        {
            printf("Not Found\n");
        }
    }
    //最后一次输出
    if(a[j] >=0 && a[j] < n)
    {
        printf("%s %s %s %c %s", q[a[j]].name, q[a[j]].fphone,
               q[a[j]].mphone, q[a[j]].gender, q[a[j]].birth);
    }
    else
    {
        printf("Not Found");
    }
}

嗐,我发现结尾有回车也没被卡。

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

		int N = in.nextInt();//读入一个整数
		in.nextLine(); //想不到竟然这个也有留在缓冲区的,相当关于getchar
		String[] contact = new String[N];//字符串数组,存每一行信息
		for(int i=0; i<N; i++) {
			contact[i] = in.nextLine();
		}
		
		int count = in.nextInt();//读入一个整数
		String[] temp = new String[5];//字符串数组,装被空格分隔开的每一行信息
		int index;
		
		for (int i = 0; i < count; i++) {
			index = in.nextInt();// 要找的索引
			if (index >= N || index < 0) {
				System.out.println("Not Found");
			} else {
				temp = contact[index].split(" ");// 按照空格拆成字符串,换个顺序输出
				System.out.println(temp[0] + " " + temp[3] + " " + temp[4] + " " + temp[2] + " " + temp[1]);
			}
		}
    }
}

7-35 有理数均值

#include<stdio.h>

long commomDivisor(long s, long b)
{
    long tmp1, tmp2;
    if(s<b)
    {
        tmp1 = s;
        s = b;
        b = tmp1;
    }
    while(b != 0)
    {

        tmp2 = b;
        b = s%b;
        s = tmp2;
    }
    return s;
}

int main()
{

    int N = 0;
    scanf("%d", &N);
    long a[N];
    long b[N];

    for(int i=0; i<N; i++)
    {
        scanf("%ld/%ld", &a[i], &b[i]);
    }

    //求和
    long top ,bottom ,divisor;
    for(int i=0; i<N-1; i++)
    {
        top = a[i]*b[i+1] + a[i+1]*b[i]; //因为没有约分就去乘法了,怕数据大
        bottom = b[i]*b[i+1];

        divisor = commomDivisor(top, bottom);

        a[i+1] = top/divisor;
        b[i+1] = bottom/divisor;
    }


    //求平均
    divisor = commomDivisor(a[N-1], b[N-1]*N);
    top = a[N-1]/divisor;
    bottom = b[N-1]*N/divisor;

    if(bottom == 1)
    {
        printf("%d", (int)top);
    }
    else
    {
        printf("%d/%d", (int)top, (int)bottom);
    }
    return 0;
}

7-36 复数四则运算

%+输出自带的正负号

#include<stdio.h>
#include<math.h>

# define Z 0.04

int main()
{

    float a, b, c, d;
    scanf("%f %f %f %f", &a, &b, &c, &d);
    //加法
    if(fabs(a+c) <= Z && fabs(b+d) <= Z)
    {
        printf("(%.1f%+.1fi) + (%.1f%+.1fi) = 0.0\n",a,b,c,d);
    }
    else if(fabs(a+c) <= Z)
    {
        printf("(%.1f%+.1fi) + (%.1f%+.1fi) = %.1fi\n",a,b,c,d,b+d);
    }
    else if(fabs(b+d) <= Z)
    {
        printf("(%.1f%+.1fi) + (%.1f%+.1fi) = %.1f\n",a,b,c,d,a+c);
    }
    else
    {
        printf("(%.1f%+.1fi) + (%.1f%+.1fi) = %.1f%+.1fi\n",a,b,c,d,a+c,b+d);
    }
    //减法
    if(fabs(a-c) <= Z && fabs(b-d) <= Z)
    {
        printf("(%.1f%+.1fi) - (%.1f%+.1fi) = 0.0\n",a,b,c,d);
    }
    else if(fabs(a-c) <= Z)
    {
        printf("(%.1f%+.1fi) - (%.1f%+.1fi) = %.1fi\n",a,b,c,d,b-d);
    }
    else if(fabs(b-d) <= Z)
    {
        printf("(%.1f%+.1fi) - (%.1f%+.1fi) = %.1f\n",a,b,c,d,a-c);
    }
    else
    {
        printf("(%.1f%+.1fi) - (%.1f%+.1fi) = %.1f%+.1fi\n",a,b,c,d,a-c,b-d);
    }
    //乘法
    if(fabs(a*c-b*d) <= Z && fabs(b*c+a*d) <= Z)
    {
        printf("(%.1f%+.1fi) * (%.1f%+.1fi) = 0.0\n",a,b,c,d);
    }
    else if(fabs(a*c-b*d) <= Z)
    {
        printf("(%.1f%+.1fi) * (%.1f%+.1fi) = %.1fi\n",a,b,c,d,b*c+a*d);
    }
    else if(fabs(b*c+a*d) <= Z)
    {
        printf("(%.1f%+.1fi) * (%.1f%+.1fi) = %.1f\n",a,b,c,d,a*c-b*d);
    }
    else
    {
        printf("(%.1f%+.1fi) * (%.1f%+.1fi) = %.1f%+.1fi\n",a,b,c,d,a*c-b*d,b*c+a*d);
    }
    //除法
    float x = a*c+b*d;
    //printf("%f\n", x);
    float y = b*c-a*d;
    //printf("%f\n", y);
    float bottom = c*c + d*d;
    //printf("%f\n", bottom);
    if(fabs(x)<=Z && fabs(y)<=Z)
    {
        printf("(%.1f%+.1fi) / (%.1f%+.1fi) = 0.0",a,b,c,d);
    }
    else if(fabs(x)<=Z)
    {
        printf("(%.1f%+.1fi) / (%.1f%+.1fi) = %.1fi",a,b,c,d,y/bottom);
    }
    else if(fabs(y)<=Z)
    {
        printf("(%.1f%+.1fi) / (%.1f%+.1fi) = %.1f",a,b,c,d,x/bottom);
    }
    else
    {
        printf("(%.1f%+.1fi) / (%.1f%+.1fi) = %.1f%+.1fi",a,b,c,d,x/bottom,y/bottom);
    }
    return 0;
}

7-37 整数分解为若干项之和

原作者,感觉真的写的很清楚,转载一波,代码不会写自己去链接里看嚯。
看到这题第一反应是减而治之。很像全排列问题,先写出第一项,再写出剩下的数的分解项。一起来分析步骤。
 首先假设我们要求 F ( 4 ) F(4) F(4), 即写出 n = 4 n=4 n=4 的所有分解项。那么我们可以先写出第 1 位的分解项的所有可能。即 k 1 = 1 , 2 , 3 , 4 k_1=1,2,3,4 k1=1,2,3,4。对于每个 k 1 k_1 k1,我们只需求解它的子问题 F ( n − k 1 ) F(n-k_1) F(nk1)
 例如:对于 F = 4 F=4 F=4 的情况,第一位 k i k_i ki 所有可能的值为 k i = 1 , 2 , 3 , 4 k_i=1,2,3,4 ki=1,2,3,4 。对于 k i = 1 k_i=1 ki=1,问题被分解成了 F ( 4 ) = 1 + F ( 3 ) F(4)= 1 + F(3) F(4=1+F(3) 。递归这个过程,得到一棵如下的树:
在这里插入图片描述
由于题目中要求结果序列升序排列,所以我们要去除重复情况,分析后发现:

对于重复情况,结果序列会出现一个降序的子序列。即为了不重复,我们要保证 k i − 1 < = k i k_{i-1}<=k_i ki1<=ki
整理一下,可得:处于区间 [ 0 , k i − 1 − 1 ] ⋃ ( ⌊ n 2 ⌋ , n ) [0,k_{i-1}-1]\bigcup(\lfloor\frac n2\rfloor,n) [0,ki11](2n,n) 的情况必须舍去,我们只需要区间 [ k i − 1 , ⌊ n 2 ⌋ ] ⋃ { n } [k_{i-1},\lfloor\frac n2\rfloor]\bigcup\{n\} [ki1,2n]{n} 便可。
对于 F = 4 F=4 F=4 ,我们可以看做是 F ( 5 ) = 1 + F ( 4 ) F(5)=1+F(4) F(5)=1+F(4) ,可得 k i − 1 = 1 k_{i-1}=1 ki1=1,带入刚才推导出的公式得第 1 1 1 位的分解项的所有值为 i = 1 , 2 , 4 i=1,2,4 i=1,2,4。对于 i = 1 i=1 i=1 这种情况,问题被分解成了 1 + F ( n − 1 ) = = 1 + F ( 3 ) 1 + F(n-1) == 1 + F(3) 1+F(n1)==1+F(3) 。递归得:
在这里插入图片描述
递归公式也不难写出来:
F ( n ) = k i + F ( n − k i ) ,   ( n > 0 ) F(n)=k_i+F(n-k_i),\ (n>0) F(n)=ki+F(nki), (n>0)
 相信看到这里很多同学已经能用DFS解出来了,估计核心代码在3、4行左右。

#include<stdio.h>

int N;

int s[31]; // 存放划分结果
int top = -1; // 数组指针
int count = 0; // 统计输出的次数
int sum = 0; // 拆分项累加和

void division (int i);

int main ()
{
    scanf ("%d", &N);
    division (1);
    return 0;
}

void division (int i)
{
    // 输出
    if (sum == N)
    {
        count ++;
        printf("%d=", N);
        int k;
        for (k=0; k<top; k++)
        {
            printf("%d+", s[k]);
        }
        if (count%4 == 0)
        {
            printf("%d\n", s[top]);
        }
        else if(s[top] == N)
        {
            printf("%d", s[top]);
        }
        else
        {
            printf("%d;", s[top]);
        }
        return;
    }
    //递归出口
    if (sum > N)
    {
        return;
    }
    // 算法主体
    for (int j=i; j<=N; j++)
    {
        s[++top] = j;
        sum += j;
        division (j);
        sum -= j;
        top --;
    }
}

但是看到几十层的递归栈······打扰了。我决定再推一下递推式,毕竟性能快好多不是。

下面根据递归式去推导递推。

显然,F(n)的分解式不会超过 n n n 项,也就是第一次DFS到底时, 1 + 1 + 1 + ⋅ ⋅ ⋅ + 1 ⏟ n 个 1 \underbrace{1+1+1+···+1}_{n个1} n1 1+1+1++1这种情况,设为序列 U U U。我们从这种情况开始反推。由于公式为 F ( n ) = k i + F ( n − k i ) F(n)=k_i+F(n-k_i) F(n)=ki+F(nki), 将序列 U U U 末尾2位代入公式,得 :
{ k n − 1 = 1 n − k n − 1 = = n − 1 = = 1 ⇒ n = 2 \begin{cases} k_{n-1}=1\\ n-k_{n-1}==n-1==1\Rightarrow n=2\end{cases} {kn1=1nkn1==n1==1n=2

此时再判定有无处于区间 [ k n − 1 , ⌊ n 2 ⌋ ] ⋃ { n } [k_{n-1},\lfloor\frac n2\rfloor]\bigcup\{n\} [kn1,2n]{n} 的其他 k n − 1 k_{n-1} kn1,有的话每次只需要处理比当前 k n − 1 k_{n-1} kn1 大 1 的情况,即如果 j = ⌊ n 2 ⌋ − k n − 1 > 0 j=\lfloor\frac n2\rfloor-k_{n-1}>0 j=2nkn1>0,进行j次循环分解,每次执行 n − = k i + 1 n-=k_i+1 n=ki+1 ,遇到逆序情况则退出循环,最后存留的 n n n 即为最后一位的值。与递归相反,整个递推过程当 n = 30 n=30 n=30 时自然结束递推了。

7-38 数列求和-加强版

一列一列的加,只存一列的和就已经砍掉很多了。

#include <iostream>
#include<stack>
#include<stdlib.h>
using namespace std;

int main ()
{
    int A, N;
    scanf("%d", &A);
    scanf("%d", &N);
    if(N == 0){
        printf("0");
        return 0;
    }
    stack <int>stk;

    long unit;
    long tmp = 0;
    while(N > 0)
    {
        unit = A*N + tmp;
        stk.push(unit%10);
        tmp = unit/10;
        N--;
    }

    if(tmp != 0)
    {
        cout << tmp;
    }
    while(!stk.empty())
    {
        cout << stk.top();
        stk.pop();
    }
    return 0;
}

总结

Java解题的话,还是有必要学习一下快读快写模板。注意每道题的边界值。

  • 4
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值