一、喝汽水——迭代
有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?
”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。
如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?
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 count = 0;//能换到的汽水瓶数量
if(n==1 || n==0){
System.out.println(0);
}
while(n>1){
count = count + n/3;
n = n%3 + n/3;//每一个循环,空瓶数量等于没拿去换的+换来喝完的
if(n==2){
n++;
}
}
System.out.println(count);
}
}
}
二、字符串十六进制转十进制
写出一个程序,接受一个十六进制的字符串,输出该数值的十进制字符串。(多组同时输入 )
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String hex_num = sc.next().substring(2);//接受一个十六进制的字符串,从下标2的字符开始截取
int dec_num = Integer.parseInt(hex_num,16);//把十六进制转为十进制整型
System.out.println(dec_num);
}
}
}
三、数组中出现次数超过一半的数字
数组中有一个数字出现的次数超过数组长度的一半,请找出这个数字。例如输入一个长度为9的数组{1,2,3,2,2,2,5,4,2}。由于数字2在数组中出现了5次,超过数组长度的一半,因此输出2。如果不存在则输出0。
import java.util.*;
public class SortTest
{
public static void main(String[] args)
{
int[] a ={1,2,3,2,2,2,5,4,2};
System.out.println(MoreThanHalfNum_Solution(a));
}
public static int MoreThanHalfNum_Solution(int [] array) {
Arrays.sort(array);//默认快排,时间复杂度O(NlogN)
int len = array.length;
if(len == 0)return 0;
if(len == 1)return 1;
int n=0;
int mid=0;
int count=0;
mid = array[(len+1)/2-1];//为8则mid=4,为9则mid=5
for(int i=0;i<len;i++){
if(mid == array[i]){
count++;
}
}
if(count>=(len/2+1)){
return mid;
}else{
return 0;
}
}
}
四、字符串分割为长度为8的字符串数组
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String s = sc.nextLine();//读入一整行
int len = s.length();
if(len%8 != 0){
s=s+"00000000";
}
while(s.length()>=8){
System.out.println(s.substring(0,8));//从0开始,不含8
s = s.substring(8);//迭代思想
}
}
}
}
五、(sort)给定n个字符串,请对n个字符串按照字典序排列
import java.util.Scanner;
import java.util.Arrays;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int num = sc.nextInt();
String[] s = new String[num];//字符串数组,[num]输入大小,("X")输入初始化字符内容
for(int i=0;i<num;i++){
s[i]=sc.next();
}
Arrays.sort(s);//也可用于给字符串排序
for(int i=0;i<s.length;i++){
System.out.println(s[i]);
}
}
}
六、数组乘法
如果A是个x行y列的矩阵,B是个y行z列的矩阵,把A和B相乘,其结果将是另一个x行z列的矩阵C。这个矩阵的每个元素是由下面的公式决定的:
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
int x = sc.nextInt();//第1个矩阵的行数
int y = sc.nextInt();//第1个矩阵的列数和第2个矩阵的行数
int z = sc.nextInt();//第2个矩阵的列数
int count = 0;
int[][] m1 = new int[x][y];//矩阵1
int[][] m2 = new int[y][z];//矩阵2
int[][] res = new int[x][z];//结果
//输入m1
for(int i=0;i<x;i++){
for(int j=0;j<y;j++){
m1[i][j]=sc.nextInt();
}
}
//输入m2
for(int i=0;i<y;i++){
for(int j=0;j<z;j++){
m2[i][j]=sc.nextInt();
}
}
//结果res
for(int i=0;i<x;i++){
for(int j=0;j<z;j++){
for(int k=0;k<y;k++){//x=1,z=1时的数=矩阵1的行*矩阵2的列,y*y
res[i][j] = res[i][j] + m1[i][k]*m2[k][j];
}
}
}
//输出结果
for(int i=0;i<x;i++){
for(int j=0;j<z;j++){
System.out.print(res[i][j]+" ");
}
System.out.println();
}
}
sc.close();
}
}
七、输入n个整数,输出其中最小的k个(易错)
import java.util.Scanner;
import java.util.Arrays;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
int num1 = sc.nextInt();
int num2 = sc.nextInt();
//String s = sc.nextLine();//nextLine()是读入Enter之前所有数据,不能用这个
int[] n = new int[num1];
for(int i=0;i<num1;i++){
n[i] = sc.nextInt();
}
Arrays.sort(n);
for(int j=0;j<num2;j++){
if(j==(num2-1))
System.out.println(n[j]);//为了最后一个数后面不加空格!
else
System.out.print(n[j]+" ");
}
}
}
nextLine()是读入Enter之前所有数据,前面不要有nextInt()之类的!
八、计算一个数字的立方根,不使用库函数
import java.util.*;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
double n = sc.nextDouble();
System.out.printf("%.1f",getCubeRoot(n));
}
sc.close();
}
//利用二分查找思想
public static double getCubeRoot(double input){
double min = 0;
double max = input;
double mid =0;
while((max-min)>0.0001){
mid =(max + min)/2;
if(mid*mid*mid == input){
return mid;
}else if(mid*mid*mid > input){
max = mid;
}else if(mid*mid*mid < input){
min = mid;
}
}
return max;
}
}
九、字符串计算器
给定一个字符串描述的算术表达式,计算出结果值。
输入字符串长度不超过100,合法的字符包括”+, -, *, /, (, )”,”0-9”,字符串内容的合法性及表达式语法的合法性由做题者检查。本题目只涉及整型计算。
print(eval(input()))
如果是计算 算数表达式四则运算:
print(input())
十、输出7有关数字的个数
输出7有关数字的个数,包括7的倍数,还有包含7的数字(如17,27,37…70,71,72,73…)的个数(一组测试用例里可能有多组数据,请注意处理)
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 num=0;
for(int i=1;i<=N;i++){
//7的倍数
if(i%7==0){
num++;
}
//包含7的数字,部分与前面有重复!
String s = Integer.toString(i);
char[] c = s.toCharArray();
for(int j=0;j<c.length;j++){
if(c[j]=='7' && i%7!=0){
num++;
break;//因为有的数里不止一个7,应当排除同一个数计算多次的情况
}
}
}
System.out.println(num);
}
sc.close();
}
}
十一、按字节截取字符串(带汉字)
编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。但是要保证汉字不被截半个,如"我ABC"4,应该截为"我AB",输入"我ABC汉DEF"6,应该输出为"我ABC"而不是"我ABC+汉的半个"。
//一个汉字占两个字节,一个字符有一个ACSCII码,占一个字节
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String s = sc.next();
int num = sc.nextInt();
char[] c = s.toCharArray();
int count=0;
int i=0;//注意:i的定义必须放在循环外面,这样后面输出时,i才可以找得到
//变量的作用域是在当前块中,出了块就失效了!
for(i=0;i<s.length();i++){
if(c[i]>='a'&&c[i]<='z' || c[i]>='A'&&c[i]<='Z'){
count++;
}else{
count=count+2;//如果不是,就肯定是汉字,占两个字节
}
if(count>num){//超过直接结束循环,此时的i-1是最后一个字符的位姿
break;
}
}
System.out.println(s.substring(0,i));
}
sc.close();
}
}
——注意点:
变量的作用域是从定义点起,到当前代码块结束,以及该代码块的内部块中。
如果将int i=0定义在for循环内部,则无法在外部根据i的值进行输出,即失效!
十二、删除字符串中出现次数最少的字符
实现删除字符串中出现次数最少的字符,若多个字符出现次数一样,则都删除。输出删除这些单词后的字符串,字符串中其它字符保持原来的顺序。
(注意每个输入文件有多组输入,即多个字符串用回车隔开)
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String s = sc.nextLine();
char[] c = s.toCharArray();
int[] num = new int[26];//存放26个字母分别出现次数的数组
int len = c.length;
//int min = Integer.MAX_VALUE;
//统计各个字母出现的次数
for(int i=0;i<len;i++){
num[c[i]-'a']++;
//min = Math.min(num[c[i]-'a'],min);//找到出现次数最少的那个,注意:没有出现的字母的所对应的数组值为0
}
int min = num[c[0]-'a'];
for(int i=0;i<len;i++){
if(num[c[i]-'a']<=min){
min=num[c[i]-'a'];
}
}
//把非最少的字符输出
for(int i=0;i<len;i++){
if(num[c[i]-'a']>min){
System.out.print(c[i]);
}
}
System.out.println();
}
}
}
十三、数字标注
【注意】输出后必须换行!!!!
将一个字符中所有出现的数字前后加上符号“*”,其他字符保持不变
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
String s = sc.nextLine();
StringBuffer sb = new StringBuffer();
for(int i=0;i<s.length();i++){
if(s.charAt(i)>='0' && s.charAt(i)<='9'){
sb.append("*"+s.charAt(i)+"*");
}else{
sb.append(s.charAt(i));
}
}
System.out.println(sb.toString().replace("**",""));
//使用StringBuffer的toString()方法,可以将StringBuffer转换成String,
//String才便于用此类格式的replace()方法
}
sc.close();
}
}
注意:输出StringBuffer时,一般采用sb.toSting()转化为String输出,但是不这样也能输出,因为StringBuffer是带缓存的,最好转为String输出; 在这里,是由于常用的repalce()方法是String类的方法!
十四、放苹果——递归
【题目描述】:
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。
import java.util.Scanner;
public class Main{
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
while(sc.hasNext()){
int K=0;
int m=sc.nextInt();
int n=sc.nextInt();
System.out.println(count(m,n));
}
sc.close();
}
//分两种情况:
//1.有盘子为空count(m,n-i)——m个放在n-i个盘子上;
//2.所有盘子上都有count(m-n,n)——将m-n个放在n个盘子上。
public static int count(int m,int n){//m个苹果,n个盘子
if(m<0){
return 0;
}else if(m==1 || n==1){
return 1;
}else{
return count(m,n-1) + count(m-n,n);
}
}
}
十五、跳跃游戏
给定一个非负整数数组,你最初位于数组的第一个位置。
数组中的每个元素代表你在该位置可以跳跃的最大长度。
判断你是否能够到达最后一个位置。
示例 1:
输入: [2,3,1,1,4]
输出: true
解释: 我们可以先跳 1 步,从位置 0 到达 位置 1, 然后再从位置 1 跳 3 步到达最后一个位置。
示例 2:
输入: [3,2,1,0,4]
输出: false
解释: 无论怎样,你总会到达索引为 3 的位置。但该位置的最大跳跃长度是 0 , 所以你永远不可能到达最后一个位置。
class Solution {
public boolean canJump(int[] nums) {
int len = nums.length;
int n=1;
for(int i=len-2;i>=0;i--){
if(nums[i]>=n){//n表示到达末尾的步数
n=1;//如果可以到达末尾,就截断,从头开始
}else{
n++;
}
if(n>1 && i==0){//到达首部还未找到
return false;
}
}
return true;
}
}
class Solution {
public int addDigits(int num) {
if(num/10==0) {
return num;
}
int sum = 0;
while(num/10 != 0){
sum = 0;
while(num != 0){
sum = sum + num%10;//8 11 1 2
num = num/10;//3 0 1 0
}
num = sum; //11 2
}
return sum;
}
}
O(1)解法:return (num - 1) % 9 + 1;