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);
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("%.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);
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)
{
int end = 0;
while(output[end] == 'a')
{
end += 2;
}
if(end != 0)
{
end -= 1;
}
char before;
for(int i=count-2; i>=end; i--)
{
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++];
}
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)
{
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--;
}
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;
int n;
scanf("%d", &n);
int m = n;
int p = 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)
{
strcpy(temp, p+strlen(mark));
*p='\0';
strcat(str, temp);
}
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];
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);
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];
char birth[11];
char gender;
char fphone[17];
char mphone[17];
};
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);
}
}
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();
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;
float y = b*c-a*d;
float bottom = c*c + d*d;
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(\lfloor\frac n2\rfloor,n)
[0,ki?1??1]?(?2n??,n) 的情况必须舍去,我们只需要区间
[
k
i
?
1
,
?
n
2
?
]
?
{
n
}
[k_{i-1},\lfloor\frac n2\rfloor]\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==1\Rightarrow n=2\end{cases}
{kn?1?=1n?kn?1?==n?1==1?n=2?
此时再判定有无处于区间
[
k
n
?
1
,
?
n
2
?
]
?
{
n
}
[k_{n-1},\lfloor\frac n2\rfloor]\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=\lfloor\frac n2\rfloor-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 <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解题的话,还是有必要学习一下快读快写模板。注意每道题的边界值。
|