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

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

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

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

文章目录

7-1 厘米换算英尺英寸7-2 然后是几点7-3 逆序的三位数7-4 BCD解密7-5 表格输出7-6 混合类型数据格式化输入7-7 12-24小时制7-8 超速判断7-9 用天平找小球7-10 计算工资7-11 分段计算居民水费7-12 两个数的简单计算器7-13 日K蜡烛图7-14 求整数段和7-15 计算圆周率7-16 求符合给定条件的整数集7-17 爬动的蠕虫7-18 二分法求多项式单根7-19 支票面额7-20 打印九九口诀表7-21 求特殊方程的正整数解7--22 龟兔赛跑7-23 币值转换7-24 约分最简分式7-25 念数字7-26 单词长度7-27 冒泡法排序7-28 猴子选大王7-29 删除字符串中的子串7-30 字符串的冒泡排序7-31 字符串循环左移7-32 说反话-加强版7-33 有理数加法7-34 通讯录的录入与显示7-35 有理数均值7-36 复数四则运算7-37 整数分解为若干项之和7-38 数列求和-加强版 总结


7-1 厘米换算英尺英寸
#include 
#include 
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 
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 
#include 

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 
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
int main()
{
 printf("------------------------------------n");
 printf("Province      Area(km2)   Pop.(10K)n");
 printf("------------------------------------n");
 printf("Anhui         139600.00   6461.00n");
 printf("Beijing        16410.54   1180.70n");
 printf("Chongqing      82400.00   3144.23n");
 printf("Shanghai        6340.50   1360.26n");
 printf("Zhejiang      101800.00   4894.00n");
 printf("------------------------------------n");
 return 0;
}
7-6 混合类型数据格式化输入

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

#include
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
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
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
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
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
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
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
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
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 
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 
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%dn",i,j,k);
        else
        printf("%d%d%d ",i,j,k);
       }
7-17 爬动的蠕虫
#include 
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 
#include
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(" %.2fn", 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(" %.2fn", 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 %.2fn", 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 

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 

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 

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 %dn", r, l);
                put = 0;
                break;
            }
        }
    }
    if(put)
    {
        printf("No Solution");
    }
    return 0;
}
7–22 龟兔赛跑
#include 

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 

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 
7-24 约分最简分式 

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

#include 

int commomDivisor(int s, int b)
{
    int tmp1, tmp2;
    if(s 
7-25 念数字 

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

#include 
#include
#include
using namespace std;

int main ()
{
    int t, tmp;
    stack 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 

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 
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 
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
#include

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

    gets(str);
    gets(mark);

    while((p=strstr(str,mark)) != NULL)
    {
        //在字符串str中查找第一次出现字符串mark的位置,不包含终止符 ''。
        strcpy(temp, p+strlen(mark));
        //把mark所指向的字符串复制到temp, 相当于去覆盖掉了
        *p=''; 
        //将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
#include

int main()
{
    int N, K;
    scanf("%d %d", &N, &K);
    char arr[N][11]; //char *arr[N]
    for(int i=0; i 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("%sn", 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
#include

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

long commomDivisor(long s, long b)
{
    long tmp1, tmp2;
    if(s 
7-34 通讯录的录入与显示 

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

#include 
#include 

struct contacts
{
    char name[11];  //字符串结尾有,长度需加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 %sn", q[a[j]].name, q[a[j]].fphone,
                   q[a[j]].mphone, q[a[j]].gender, q[a[j]].birth);
        }
        else
        {
            printf("Not Foundn");
        }
    }
    //最后一次输出
    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 || 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

long commomDivisor(long s, long b)
{
    long tmp1, tmp2;
    if(s 
7-36 复数四则运算 

%+输出自带的正负号

#include
#include

# 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.0n",a,b,c,d);
    }
    else if(fabs(a+c) <= Z)
    {
        printf("(%.1f%+.1fi) + (%.1f%+.1fi) = %.1fin",a,b,c,d,b+d);
    }
    else if(fabs(b+d) <= Z)
    {
        printf("(%.1f%+.1fi) + (%.1f%+.1fi) = %.1fn",a,b,c,d,a+c);
    }
    else
    {
        printf("(%.1f%+.1fi) + (%.1f%+.1fi) = %.1f%+.1fin",a,b,c,d,a+c,b+d);
    }
    //减法
    if(fabs(a-c) <= Z && fabs(b-d) <= Z)
    {
        printf("(%.1f%+.1fi) - (%.1f%+.1fi) = 0.0n",a,b,c,d);
    }
    else if(fabs(a-c) <= Z)
    {
        printf("(%.1f%+.1fi) - (%.1f%+.1fi) = %.1fin",a,b,c,d,b-d);
    }
    else if(fabs(b-d) <= Z)
    {
        printf("(%.1f%+.1fi) - (%.1f%+.1fi) = %.1fn",a,b,c,d,a-c);
    }
    else
    {
        printf("(%.1f%+.1fi) - (%.1f%+.1fi) = %.1f%+.1fin",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.0n",a,b,c,d);
    }
    else if(fabs(a*c-b*d) <= Z)
    {
        printf("(%.1f%+.1fi) * (%.1f%+.1fi) = %.1fin",a,b,c,d,b*c+a*d);
    }
    else if(fabs(b*c+a*d) <= Z)
    {
        printf("(%.1f%+.1fi) * (%.1f%+.1fi) = %.1fn",a,b,c,d,a*c-b*d);
    }
    else
    {
        printf("(%.1f%+.1fi) * (%.1f%+.1fi) = %.1f%+.1fin",a,b,c,d,a*c-b*d,b*c+a*d);
    }
    //除法
    float x = a*c+b*d;
    //printf("%fn", x);
    float y = b*c-a*d;
    //printf("%fn", y);
    float bottom = c*c + d*d;
    //printf("%fn", 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(n−k1​) 。
 例如:对于 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 ki−1​<=ki​ 。
整理一下,可得:处于区间 [ 0 , k i − 1 − 1 ] ⋃ ( ⌊ n 2 ⌋ , n ) [0,k_{i-1}-1]bigcup(lfloorfrac n2rfloor,n) [0,ki−1​−1]⋃(⌊2n​⌋,n) 的情况必须舍去,我们只需要区间 [ k i − 1 , ⌊ n 2 ⌋ ] ⋃ { n } [k_{i-1},lfloorfrac n2rfloor]bigcup{n} [ki−1​,⌊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 ki−1​=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(n−1)==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(n−ki​), (n>0)
 相信看到这里很多同学已经能用DFS解出来了,估计核心代码在3、4行左右。但是看到几十层的递归栈······打扰了。我决定再推一下递推式,毕竟性能快好多不是。

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

显然,F(n)的分解式不会超过 n n n 项,也就是第一次DFS到底时, 1 + 1 + 1 + ⋅ ⋅ ⋅ + 1 ⏟ n 个 1 underbrace{1+1+1+···+1}_{n个1} n个1 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(n−ki​), 将序列 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==1Rightarrow n=2end{cases} {kn−1​=1n−kn−1​==n−1==1⇒n=2​

此时再判定有无处于区间 [ k n − 1 , ⌊ n 2 ⌋ ] ⋃ { n } [k_{n-1},lfloorfrac n2rfloor]bigcup{n} [kn−1​,⌊2n​⌋]⋃{n} 的其他 k n − 1 k_{n-1} kn−1​,有的话每次只需要处理比当前 k n − 1 k_{n-1} kn−1​ 大 1 的情况,即如果 j = ⌊ n 2 ⌋ − k n − 1 > 0 j=lfloorfrac n2rfloor-k_{n-1}>0 j=⌊2n​⌋−kn−1​>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 
#include
#include
using namespace std;

int main ()
{
    int A, N;
    scanf("%d", &A);
    scanf("%d", &N);
    if(N == 0){
        printf("0");
        return 0;
    }
    stack 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解题的话,还是有必要学习一下快读快写模板。注意每道题的边界值。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5716072.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存