前言:java编写,代码尽可能带注释,部分题目附上解题思路。力求方便,所以不写如有错误,请指出,谢谢。
查找排序
1、百钱买百鸡问题2、统计每个月兔子总数3、查找组成一个偶数最接近的两个素数4、公共字串计算5、成绩排序6、Redraiment的走法7、字符统计8、迷宫问题9、字符串排序10、质数因子11、自守数12、多线程
1、百钱买百鸡问题
题目描述
公元前五世纪,我国古代数学家张丘建在《算经》一书中提出了“百鸡问题”:鸡翁一值钱五,鸡母一值钱三,鸡雏三值钱一。百钱买百鸡,问鸡翁、鸡母、鸡雏各几何?
详细描述:
接口说明
原型:
int GetResult
(vector
&list
)
输入参数:
无
输出参数(指针指向的内存区域保证有效):
list 鸡翁、鸡母、鸡雏组合的列表
返回值:
-1 失败
0 成功
import java
.util
.Scanner
;
public class Main{
public static void main(String
[] args
){
Scanner sc
= new Scanner(System
.in
);
while(sc
.hasNext() ){
int n
= sc
.nextInt();
int n1
= 0, n2
= 0, n3
= 0;
for(n1
= 0; n1
<=14; n1
++ ){
for(n2
= 25; n2
>=0; n2
--){
int sum
= 7 * n1
+ 4 * n2
;
if(sum
== 100){
n3
= 100-n1
-n2
;
System
.out
.println(n1
+" "+n2
+ " "+n3
);
}
}
}
for(n1
= 0; n1
<= 14; n1
++){
double j
;
if(n1
== 0){
j
= 25;
}else{
j
= (100-7*n1
)/4.0;
}
if(Math
.abs(j
- Math
.round(j
)) < 1e-6){
n2
= (int)j
;
n3
= 100 - n1
- n2
;
System
.out
.println(n1
+" "+n2
+ " "+n3
);
}
}
}
}
}
2、统计每个月兔子总数
题目描述
有一只兔子,从出生后第3个月起每个月都生一只兔子,小兔子长到第三个月后每个月又生一只兔子,假如兔子都不死,问每个月的兔子总数为多少?
/**
* 统计出兔子总数。
*
* @param monthCount 第几个月
* @return 兔子总数
*/
public static int getTotalCount
(int monthCount
)
{
return 0
;
}
import java
.util
.Scanner
;
public class Main{
public static void main(String
[] args
){
Scanner sc
= new Scanner(System
.in
);
while(sc
.hasNext() ){
int month
= sc
.nextInt();
System
.out
.println(Main
.getTotalCount(month
));
}
}
public static int getTotalCount(int monthCount
){
if(monthCount
< 0)
return 0;
int oneMonthOld
= 1;
int twoMonthOld
= 0;
int threeMonthOld
= 0;
for(int i
= 0; i
< monthCount
-1; i
++){
threeMonthOld
+= twoMonthOld
;
twoMonthOld
= oneMonthOld
;
oneMonthOld
= threeMonthOld
;
}
return oneMonthOld
+twoMonthOld
+threeMonthOld
;
}
}
3、查找组成一个偶数最接近的两个素数
注:这里动态规划,比较不好懂
题目描述
任意一个偶数(大于2)都可以由2个素数组成,组成偶数的2个素数有很多种情况,本题目要求输出组成指定偶数的两个素数差值最小的素数对
import java
.util
.Scanner
;
public class Main{
public static void main(String
[] args
){
Scanner sc
= new Scanner(System
.in
);
while(sc
.hasNext() ){
int even
= sc
.nextInt();
int max
= even
/2;
for(int i
= max
; i
>=2; i
--){
if(Main
.judge(i
) && Main
.judge(even
-i
)){
System
.out
.println(i
);
System
.out
.println(even
-i
);
break;
}
}
}
}
public static boolean judge(int number
){
if(number
<= 1){
return false;
}
for(int i
= 2; i
< number
; i
++){
if((number
% i
) == 0){
return false;
}
}
return true;
}
}
4、公共字串计算
题目描述
题目标题:
计算两个字符串的最大公共字串的长度,字符不区分大小写
详细描述:
接口说明
原型:
int getCommonStrLength
(char * pFirstStr, char * pSecondStr
);
输入参数:
char * pFirstStr //第一个字符串
char * pSecondStr//第二个字符串
import java
.util
.Scanner
;
public class Main{
public static void main(String
[] args
){
Scanner sc
= new Scanner(System
.in
);
while(sc
.hasNext() ){
String str1
= sc
.next();
String str2
= sc
.next();
System
.out
.println(Main
.getCommonStrLength(str1
, str2
));
}
}
public static int getCommonStrLength(String str1
, String str2
){
if(str1
== null
|| str1
.length() == 0 || str2
== null
|| str2
.length()==0){
return 0;
}
int len1
= str1
.length();
int len2
= str2
.length();
int max
= 0;
for(int i
= 0; i
< len1
;){
for(int j
= 0; j
< len2
;){
if(str1
.charAt(i
) == str2
.charAt(j
)){
int p1
= i
, p2
= j
;
int count
= 0;
while(p1
< len1
&& p2
< len2
&& str1
.charAt(p1
) == str2
.charAt(p2
)){
p1
++;
p2
++;
count
++;
}
if(count
> max
){
max
= count
;
}
}
j
++;
}
i
++;
}
return max
;
}
public static int getCommonStrLength(String str1
, String str2
) {
int len1
= str1
.length();
int len2
= str2
.length();
int[][] dp
= new int[len1
+ 1][len2
+ 1];
for (int i
= 1; i
<= len1
; i
++) {
for (int j
= 1; j
<= len2
; j
++) {
if (str1
.charAt(i
- 1) == str2
.charAt(j
- 1)) {
dp
[i
][j
] = dp
[i
- 1][j
- 1] + 1;
}
}
}
int max
= 0;
for (int i
= 0; i
<= len1
; i
++) {
for (int j
= 0; j
<= len2
; j
++) {
if (max
< dp
[i
][j
])
max
= dp
[i
][j
];
}
}
return max
;
}
}
5、成绩排序
注意:感觉同样分数同样成绩这里LinkedHashMap怕不合适吧
题目描述
查找和排序
题目:输入任意(用户,成绩)序列,可以获得成绩从高到低或从低到高的排列,相同成绩
都按先录入排列在前的规则处理。
例示:
jack 70
peter 96
Tom 70
smith 67
从高到低 成绩
peter 96
jack 70
Tom 70
smith 67
从低到高
smith 67
jack 70
Tom 70
peter 96
注:0代表从高到低,1代表从低到高
import java
.util
.*
;
public class Main{
public static void main(String
[] args
) {
Scanner sc
= new Scanner(System
.in
);
while(sc
.hasNext() ){
String name
;
Integer score
;
List
<Integer> scoreList
= new ArrayList<>();
Map
<String, Integer> map
= new LinkedHashMap<>();
int sortNum
= sc
.nextInt();
int sortMethod
= sc
.nextInt();
for(int i
= 0; i
< sortNum
; i
++){
name
= sc
.next();
score
= sc
.nextInt();
scoreList
.add(score
);
map
.put(name
+" "+score
, score
);
}
Collections
.sort(scoreList
);
if(sortMethod
== 0){
Collections
.reverse(scoreList
);
}
int pre
= -1;
for(int s
: scoreList
){
if(pre
== s
){
continue;
}
for(String key
: map
.keySet()){
if(map
.get(key
).equals(s
)){
System
.out
.println(key
);
}
}
pre
= s
;
}
}
}
}
6、Redraiment的走法
注意:最长递增序列
题目描述
Redraiment是走梅花桩的高手。Redraiment总是起点不限,从前到后,往高的桩子走,但走的步数最多,不知道为什么?你能替Redraiment研究他最多走的步数吗?
样例输入
6
2 5 1 5 4 5
样例输出
3
提示
Example:
6个点的高度各为 2 5 1 5 4 5
如从第1格开始走,最多为3步, 2 4 5
从第2格开始走,最多只有1步,5
而从第3格开始走最多有3步,1 4 5
从第5格开始走最多有2步,4 5
所以这个结果是3。
import java
.util
.*
;
public class Main {
public static void main(String
[] args
) {
Scanner input
= new Scanner(System
.in
);
while (input
.hasNextInt()) {
int n
= input
.nextInt();
int[] a
= new int[n
];
for (int i
= 0; i
< n
; i
++)
a
[i
] = input
.nextInt();
System
.out
.println(getMaxSteps(a
, n
));
}
}
public static int getMaxSteps(int [] arr
,int n
) {
int[] dp
= new int[n
];
for(int i
= 0; i
< n
; i
++){
dp
[i
] = 1;
for(int j
= 0; j
< i
; j
++){
if(arr
[j
] < arr
[i
]){
dp
[i
] = Math
.max(dp
[i
], dp
[j
]+1);
}
}
}
int max
= 0;
for(int i
= 0; i
< n
; i
++){
if(dp
[i
] > max
){
max
= dp
[i
];
}
}
return max
;
}
}
7、字符统计
题目描述
如果统计的个数相同,则按照ASCII码由小到大排序输出 。如果有其他字符,则对这些字符不用进行统计。
实现以下接口:
输入一个字符串,对字符中的各个英文字符,数字,空格进行统计(可反复调用)
按照统计个数由多到少输出统计结果,如果统计的个数相同,则按照ASII码由小到大排序输出
清空目前的统计结果,重新统计
调用者会保证:
输入的字符串以‘\0’结尾。
package zTestDay
;
import java
.util
.*
;
public class Main {
public static void main(String
[] args
) {
Scanner sc
= new Scanner(System
.in
);
while (sc
.hasNext()) {
Map
<Character, Integer> map
= new HashMap<>();
String str
= sc
.next();
for(int i
= 0; i
< str
.length(); i
++){
Character key
= str
.charAt(i
);
if((key
>= '0' && key
<= '9') || (key
>= 'A' && key
<='Z') || (key
>= 'a' && key
<='z') || key
== ' '){
if(map
.containsKey(key
) ){
map
.put(key
, map
.get(key
)+1);
}else{
map
.put(key
, 1);
}
}
}
Map
<Integer, Character> treeMap
= new TreeMap<>();
for(Character key
:map
.keySet()){
treeMap
.put(map
.get(key
) * 128 + 128 - key
, key
);
}
StringBuilder sb
= new StringBuilder();
for(Integer i
: treeMap
.keySet()){
sb
.append(treeMap
.get(i
));
}
System
.out
.println(sb
.reverse().toString());
}
}
public static void main(String
[] args
) {
Scanner sc
= new Scanner(System
.in
);
while (sc
.hasNext()) {
Map
<Character, Integer> map
= new TreeMap<>();
Set
<Integer> set
= new HashSet<>();
String str
= sc
.next();
for(int i
= 0; i
< str
.length(); i
++){
Character key
= str
.charAt(i
);
if((key
>= '0' && key
<= '9') || (key
>= 'A' && key
<='Z') || (key
>= 'a' && key
<='z') || key
== ' '){
if(map
.containsKey(key
) ){
map
.put(key
, map
.get(key
)+1);
}else{
map
.put(key
, 1);
}
set
.add(map
.get(key
));
}
}
List
<Integer> count
= new ArrayList<>();
for(Integer i
:set
){
count
.add(i
);
}
Collections
.reverse(count
);
StringBuilder sb
= new StringBuilder();
for(Integer i
: count
){
for(Character key
: map
.keySet()){
if(map
.get(key
) == i
){
sb
.append(key
);
}
}
}
System
.out
.println(sb
.toString());
}
}
}
8、迷宫问题
题目描述
定义一个二维数组N*M(其中2
<=N
<=10
;2
<=M
<=10),如5 × 5数组下所示:
int maze
[5
][5
] = {
0, 1, 0, 0, 0,
0, 1, 0, 1, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
0, 0, 0, 1, 0,
};
它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。入口点为
[0,0
],既第一空格是可以走的路。
Input
一个N × M的二维数组,表示一个迷宫。数据保证有唯一解,不考虑有多解的情况,即迷宫只有一条通道。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0
Sample Output
(0, 0
)
(1, 0
)
(2, 0
)
(2, 1
)
(2, 2
)
(2, 3
)
(2, 4
)
(3, 4
)
(4, 4
)
import java
.util
.LinkedList
;
import java
.util
.Scanner
;
public class Main {
public static void main(String
[] args
) {
Scanner sc
= new Scanner(System
.in
);
while(sc
.hasNext()){
int rows
= sc
.nextInt();
int cols
= sc
.nextInt();
int[][] maze
= new int[rows
][cols
];
for(int i
= 0; i
< rows
; i
++){
for(int j
= 0; j
< cols
; j
++){
int val
= sc
.nextInt();
if(val
== 1){
maze
[i
][j
]=-1;
}
}
}
LinkedList
<String> list
= new LinkedList<>();
findRoute(maze
, 0, 0, rows
, cols
, list
);
for(String step
: list
){
System
.out
.println(step
);
}
}
}
private static boolean findRoute(int[][] maze
, int i
, int j
, int rows
, int cols
, LinkedList
<String> list
) {
if(i
>= 0 && j
>= 0 && i
< rows
&& j
< cols
&& maze
[i
][j
] == 0){
maze
[i
][j
] = 1;
list
.add("("+i
+","+j
+")");
if(i
== rows
-1 && j
== cols
-1){
return true;
}
if(findRoute(maze
, i
+1, j
, rows
, cols
, list
)
|| findRoute(maze
, i
-1, j
, rows
, cols
, list
)
|| findRoute(maze
, i
, j
+1, rows
, cols
, list
)
|| findRoute(maze
, i
, j
-1, rows
, cols
, list
)){
return true;
}else{
maze
[i
][j
] = 0;
list
.removeLast();
return false;
}
}else{
return false;
}
}
}
9、字符串排序
注:思路不够简洁
题目描述
编写一个程序,将输入字符串中的字符按如下规则排序。
规则 1 :英文字母从 A 到 Z 排列,不区分大小写。
如,输入: Type 输出: epTy
规则 2 :同一个英文字母的大小写同时存在时,按照输入顺序排列。
如,输入: BabA 输出: aABb
规则 3 :非英文字母的其它字符保持原来的位置。
如,输入: By?e 输出: Be?y
import java
.util
.*
;
public class Main {
public static void main(String
[] args
) {
Scanner sc
= new Scanner(System
.in
);
while (sc
.hasNext()) {
String input
= sc
.nextLine();
TreeMap
<Character, String> map
= new TreeMap<>();
HashMap
<Integer, Character> hashMap
= new HashMap<>();
for (int i
= 0; i
< input
.length(); i
++) {
char c
= input
.charAt(i
);
if (Character
.isLetter(c
)) {
char lower
= Character
.toLowerCase(c
);
if (map
.containsKey(lower
)) {
map
.put(lower
, map
.get(lower
) + c
);
} else {
map
.put(lower
, c
+ "");
}
} else {
hashMap
.put(i
, c
);
}
}
StringBuilder sb
= new StringBuilder();
for (Character key
: map
.keySet()) {
sb
.append(map
.get(key
));
}
StringBuilder sb2
= new StringBuilder();
int i
= 0, j
= 0;
while (i
< input
.length()) {
if (hashMap
.containsKey(i
)) {
sb2
.append(hashMap
.get(i
));
} else if (j
< sb
.length()) {
sb2
.append(sb
.charAt(j
++));
}
i
++;
}
System
.out
.println(sb2
.toString());
}
}
}
10、质数因子
题目描述
功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )
最后一个数后面也要有空格
import java
.util
.*
;
public class Main {
public static void main(String
[] args
) {
Scanner sc
= new Scanner(System
.in
);
while (sc
.hasNext()) {
Long input
= sc
.nextLong();
ArrayList
<Integer> list
= new ArrayList<>();
int n
= 2;
while(input
>= 2){
if(input
% n
== 0){
input
= input
/ n
;
list
.add(n
);
}else{
n
++;
}
}
for(Integer i
: list
){
System
.out
.print(i
+ " ");
}
}
}
private static int getNext(int n
) {
while(true){
n
++;
if(judge(n
)){
return n
;
}
}
}
private static boolean judge(int n
) {
for(int i
= 2; i
< n
; i
++){
if(n
% i
== 0){
return false;
}
}
return true;
}
}
11、自守数
题目描述
自守数是指一个数的平方的尾数等于该数自身的自然数。
例如:25^2
= 625,76^2
= 5776,9376^2
= 87909376。请求出n以内的自守数的个数
import java
.util
.*
;
public class Main {
public static void main(String
[] args
) {
Scanner sc
= new Scanner(System
.in
);
while (sc
.hasNext()) {
Long input
= sc
.nextLong();
int cnt
= 1;
for(int i
= 1; i
<= input
; i
++){
if(judge(i
)){
cnt
++;
}
}
System
.out
.println(cnt
);
}
}
private static boolean judge(long i
) {
int count
= 1;
if(i
<= 0)
return false;
while(i
>= (long)Math
.pow(10, count
)){
count
++;
}
long square
= i
* i
;
long divisor
= (long)Math
.pow(10, count
);
if((square
- i
) % divisor
== 0){
return true;
}
return false;
}
}
12、多线程
注意:牛客上看到的通过案列Java不对,只能本地通过,牛客不通过
题目描述
问题描述:有4个线程和1个公共的字符数组。线程1的功能就是向数组输出A,线程2的功能就是向字符输出B,线程3的功能就是向数组输出C,线程4的功能就是向数组输出D。要求按顺序向数组赋值ABCDABCDABCD
import java
.util
.Scanner
;
public class Main {
public static void main(String
[] args
) throws Exception
{
Object a
= new Object();
Object b
= new Object();
Object c
= new Object();
Object d
= new Object();
Scanner sc
= new Scanner(System
.in
);
while (sc
.hasNext()){
int count
= sc
.nextInt();
Runnable pa
= new MyRunnable("A", d
, a
, count
);
Runnable pb
= new MyRunnable("B", a
, b
, count
);
Runnable pc
= new MyRunnable("C", b
, c
, count
);
Runnable pd
= new MyRunnable("D", c
, d
, count
);
new Thread(pa
).start();
Thread
.sleep(1);
new Thread(pb
).start();
Thread
.sleep(1);
new Thread(pc
).start();
Thread
.sleep(1);
new Thread(pd
).start();
}
}
}
class MyRunnable implements Runnable{
private String name
;
private Object prev
;
private Object self
;
private int count
;
MyRunnable(String name
, Object prev
, Object self
, int count
) {
this.name
= name
;
this.prev
= prev
;
this.self
= self
;
this.count
= count
;
}
@Override
public void run() {
while (count
> 0) {
synchronized (prev
){
synchronized (self
){
System
.out
.print(name
);
count
--;
self
.notify();
}
try {
prev
.wait();
} catch (InterruptedException e
) {
e
.printStackTrace();
}
}
}
}
}