寂寞的数
题目描述
道德经曰:一生二,二生三,三生万物。
对于任意正整数n,我们定义d(n)的值为为n加上组成n的各个数字的和。例如,d(23)=23+2+3=28, d(1481)=1481+1+4+8+1=1495。
因此,给定了任意一个n作为起点,你可以构造如下一个递增序列:n,d(n),d(d(n)),d(d(d(n)))…例如,从33开始的递增序列为:
33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, …
我们把n叫做d(n)的生成元,在上面的数列中,33是39的生成元,39是51的生成元,等等。有一些数字甚至可以有两个生成元,比如101,可以由91和100生成。但也有一些数字没有任何生成元,如42。我们把这样的数字称为寂寞的数字。
数据规模和约定
n< =10000
输入
一行,一个正整数n。
输出
按照升序输出小于n的所有寂寞的数字,每行一个。
样例输入
40
样例输出
1
3
5
7
9
20
31
import java.util.Scanner;
//寂寞的数
public class Main {
public static void main(String[]args) {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();
int num[]=new int[n];
boolean res[]=new boolean[n];//用来记录这个数是否是寂寞的数
for(int i=0;i<n;i++) {
res[i]=false;
}
//将非寂寞的数标记为true
for(int i=1;i<n;i++) {
num[i]=i;
int tmp=fun(num[i]);
if(tmp>=n)//如果这个非寂寞的数超过了n,则计算下一个
continue;
else//如果这个非寂寞的数在1~n-1的范围内,就标记为true
res[tmp]=true;
}
//输出所有false标记的数
for(int i=1;i<n;i++) {
if(res[i]==false) {
System.out.println(num[i]);
}
}
}
private static int fun(int i) {
int index=i;
while(i>0) {
index+=i%10;
i/=10;
}
return index;
}
}
未名湖边的烦恼
题目描述
每年冬天,北大未名湖上都是滑冰的好地方。北大体育组准备了许多冰鞋,可是人太多了,每天下午收工后,常常一双冰鞋都不剩。
每天早上,租鞋窗口都会排起长龙,假设有还鞋的m个,有需要租鞋的n个。现在的问题是,这些人有多少种排法,可以避免出现体育组没有冰鞋可租的尴尬场面。(两个同样需求的人(比如都是租鞋或都是还鞋)交换位置是同一种排法)
输入
两个整数,表示m和n。
输出
一个整数,表示队伍的排法的方案数。
样例输入
3 2
样例输出
5
import java.util.Scanner;
//未名湖边的烦恼
public class Main {
public static void main(String[]args) {
Scanner scan=new Scanner(System.in);
int m=scan.nextInt();//还鞋
int n=scan.nextInt();//租鞋
System.out.println(fun(m,n));
}
private static int fun(int m, int n) {
if(n>m)//如果租鞋的人比还鞋的人多,那么一定会出现无鞋可租的情况,排法为0
return 0;
else if(n==0)//如果没有租鞋的人,那么就只有一种排法
return 1;
else//排了一个还鞋的人,剩下的人再重新排队 和 排了一个租鞋的人,剩下的人再重新排队
return fun(m-1,n)+fun(m,n-1);
}
}
数字三角形(ALGO-124)
问题描述
(图3.1-1)示出了一个数字三角形。 请编一个程序计算从顶至底的某处的一条路径,使该路径所经过的数字的总和最大。
●每一步可沿左斜线向下或右斜线向下走;
●1<三角形行数≤100;
●三角形中的数字为整数0,1,…99;
输入格式
文件中首先读到的是三角形的行数。
接下来描述整个三角形。
输出格式
最大总和(整数)。
样例输入
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
样例输出
30
题目解析
import java.util.Scanner;
//数字三角形
public class Main {
public static void main(String[]args) {
Scanner scan=new Scanner(System.in);
int n=scan.nextInt();//行数
int num[][]=new int[100][100];
for(int i=0;i<n;i++) {
for(int j=0;j<=i;j++) {
num[i][j]=scan.nextInt();
}
}
for(int i=n-2;i>=0;i--) {
for(int j=0;j<=i;j++) {
num[i][j]+=Math.max(num[i+1][j], num[i+1][j+1]);
}
}
System.out.println(num[0][0]);
}
}
6-1 递归求二项式系数值
问题描述
输入
两个正整数k,n
输出
递归计算结果
样例输入
一个满足题目要求的输入范例。
3 10
样例输出
与上面的样例输入对应的输出。
120
import java.util.Scanner;
//6-1 递归求二项式系数值
public class Main {
public static void main(String[]args) {
Scanner scan=new Scanner(System.in);
int k,n;
k=scan.nextInt();
n=scan.nextInt();
System.out.println(C(k,n));
}
private static int C(int k, int n) {
if(k==0 || k==n)
return 1;
else
return C(k,n-1)+C(k-1,n-1);
}
}
最小乘积(基本型)
题目描述
给两组数,各n个。
请调整每组数的排列顺序,使得两组数据相同下标元素对应相乘,然后相加的和最小。要求程序输出这个最小值。
例如两组数分别为:1 3 -5和-2 4 1
那么对应乘积取和的最小值应为:
(-5) * 4 + 3 * (-2) + 1 * 1 = -25
输入
第一个行一个数T表示数据组数。后面每组数据,先读入一个n,接下来两行每行n个数,每个数的绝对值小于等于1000。
n<=8,T<=1000
输出
一个数表示答案。
样例输入
2
3
1 3 -5
-2 4 1
5
1 2 3 4 5
1 0 1 0 1
样例输出
-25
6
import java.util.Scanner;
//最小乘积(基本型)
public class Main {
public static void main(String[]args) {
Scanner scan=new Scanner(System.in);
int sum=scan.nextInt();//测试数据组数
int res;//记录最小乘积
while(sum>0) {
res=0;
int n=scan.nextInt();
int num1[]=new int[n];
int num2[]=new int[n];
for(int i=0;i<n;i++)
num1[i]=scan.nextInt();
for(int i=0;i<n;i++)
num2[i]=scan.nextInt();
sort1(num1);//从大到小排列
sort2(num2);//从小到大排列
for(int i=0;i<n;i++) {
res=res+num1[i]*num2[i];
}
System.out.println(res);
sum--;
}
}
private static void sort1(int[] num) {
for(int i=0;i<num.length-1;i++) {
for(int j=i;j<num.length;j++) {
if(num[i]<num[j]) {
int tmp=num[i];
num[i]=num[j];
num[j]=tmp;
}
}
}
}
private static void sort2(int[] num) {
for(int i=0;i<num.length-1;i++) {
for(int j=i;j<num.length;j++) {
if(num[i]>num[j]) {
int tmp=num[i];
num[i]=num[j];
num[j]=tmp;
}
}
}
}
}