[编程题] 汽水瓶
有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是5瓶,方法如下:先用9个空瓶子换3瓶汽水,喝掉3瓶满的,喝完以后4个空瓶子,用3个再换一瓶,喝掉这瓶满的,这时候剩2个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用3个空瓶子换一瓶满的还给老板。如果小张手上有n个空汽水瓶,最多可以换多少瓶汽水喝?
输入描述:
输入文件最多包含10组测试数据,每个数据占一行,仅包含一个正整数n(1<=n<=100),表示小张手上的空汽水瓶数。n=0表示输入结束,你的程序不应当处理这一行。
输出描述:
对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。
输入例子:
3
10
81
0
输出例子:
1
5
40
我的思路是一次性算出所有空瓶,然后加到一起,最后再统一除以3
注意每一次除以3后得到的数再次计算时应该加上余数
import java.util.Scanner;
public class test1015 {
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
int n;
while(sc.hasNext()){
n=sc.nextInt();
if(n==0)break;
int sum=n;
while(n/3!=0){
sum+=n/3;
int m=n%3;
n=n/3+m;
}
if(n==2)
sum++;
System.out.println(sum/3);
}
}
}
如果发现了这个问题本质递归 就更方便
*递归问题3个瓶子换1瓶水+1个空瓶子,两个瓶子换1瓶水+0个空瓶子,1个瓶子换0瓶水。
f(1) = 0
f(2) = 1
f(3) = 1
f(4) = f(2)+1 //4个瓶子,其中3个可以换1瓶水+1个空瓶,所以是f(2)+1
f(5) = f(3)+1 //3个瓶子换1瓶水+1个空瓶,所以是f(3)+1
...
f(n) = f(n-2)+1 *
import java.util.Scanner;
public class Main {
public static int f(int n){
if(n==1)return 0;
if(n==2)return 1;
return f(n-2)+1;
}
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
int n=sc.nextInt();
if(n==0)break;
System.out.println(f(n));
}
}
}
[编程题] 明明的随机数
明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤1000),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。请你协助明明完成“去重”与“排序”的工作。
Input Param
n 输入随机数的个数
inputArray n个随机整数组成的数组
Return Value
OutputArray 输出处理后的随机整数
注:测试用例保证输入参数的正确性,答题者无需验证。测试用例不止一组。
输入描述:
输入多行,先输入随机整数的个数,再输入相应个数的整数
输出描述:
返回多行,处理后的结果
输入例子:
11
10
20
40
32
67
40
20
89
300
400
15
输出例子:
10
15
20
32
40
67
89
300
400
解析:利用TreeSet非常方便的解决该问题。(写本题的时候没注意到测试用例不止一个,结果一直不对,吐血了发现是这个原因。以后一定要认真读题,不能被迷惑了)
Set的功能方法
Set 的用法:
存放的是对象的引用,没有重复对象
Set set=new HashSet();
String s1=new String("hello");
String s2=s1;
String s3=new String("world");
set.add(s1);
set.add(s2);
set.add(s3);
System.out.println(set.size());//打印集合中对象的数目 为 2。
Set 的 add()方法是如何判断对象是否已经存放在集合中?
boolean isExists=false;
Iterator iterator=set.iterator();
while(it.hasNext()) {
String oldStr=it.next();
if(newStr.equals(oldStr)){
isExists=true;
}
}
Set具有与Collection完全一样的接口,因此没有任何额外的功能,不像前面有两个不同的List。实际上Set就是Collection,只是行为不同。(这是继承与多态思想的典型应用:表现不同的行为。)Set不保存重复的元素。
Set : 存入Set的每个元素都必须是唯一的,因为Set不保存重复元素。加入Set的元素必须定义equals()方法以确保对象的唯一性。Set与Collection有完全一样的接口。Set接口不保证维护元素的次序。
HashSet : 为快速查找设计的Set。存入HashSet的对象必须定义hashCode()。
TreeSet : 保存次序的Set, 底层为树结构。使用它可以从Set中提取有序的序列。
LinkedHashSet : 具有HashSet的查询速度,且内部使用链表维护元素的顺序(插入的次序)。于是在使用迭代器遍历Set时,结果会按元素插入的次序显示。
import java.util.Scanner;
import java.util.TreeSet;
public class Main
{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while(sc.hasNext()){
TreeSet<Integer> set=new TreeSet<Integer>();
int n=sc.nextInt();
if(n>0){
for(int i=0;i<n;i++){
set.add(sc.nextInt());
}
}
for(Integer i:set){
System.out.println(i);
}
}
}
}
[编程题] 进制转换
写出一个程序,接受一个十六进制的数值字符串,输出该数值的十进制字符串。(多组同时输入 )
输入描述:
输入一个十六进制的数值字符串。
输出描述:
输出该数值的十进制字符串。
输入例子:
0xA
输出例子:
10
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 sum=0;
int j=0;
for(int i=s.length()-1;i>=2;i--){
int m=(int) Math.pow(16, j);
char c=s.charAt(i);
switch(c){
case 'A':
sum+=10*m;
break;
case 'B':
sum+=11*m;
break;
case 'C':
sum+=12*m;
break;
case 'D':
sum+=13*m;
break;
case 'E':
sum+=14*m;
break;
case 'F':
sum+=15*m;
break;
default:
String xxx=c+"";
sum+=Integer.parseInt(xxx)*m;
}
j++;
}
System.out.println(sum);
}
}
}
后来发现jdk自带进制转换方法 - - 受教了 很方便
public class Main {
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while (sc.hasNext()){
String str=sc.next().substring(2);
System.out.println(Integer.parseInt(str,16));
}
}
} v
1、十进制转化为N进制
Integer.toBinaryString(int i)//返回的是i的二进制表示,返回类型为String
Integer.toString(int i,int radix)//返回的是i的二进制表示,返回类型为String,但是负数不适用。
Integer.toHexString(int i)//返回16进制
Integer.toOctalString(int i)//返回8进制
System.out.println(Integer.toBinaryString(5));//101
System.out.println(Integer.toBinaryString(-5));//-5的二进制的补码形式
System.out.println(Integer.toString(5,2)//101
System.out.println(Integer.toString(-5,2)//结果不对,负数不能用此函数
2、N进制转化为十进制
Integer.parseInt(String s,int radix)//radix进制的s,转化为十进制,返回类型为int
Integer.valueOf(String s,int radix)//同上
看到了别人写的方法 也比我的简单 贴上来学习
1.通过stringbuffer构造字符串 用reverse方法 使得计数可以从0开始
2.使用substring明显更方面
3.大A的ascii码65 小a97 '0'的为48 要记住 使用更快捷
//其实不记住也行 通过Integer.valueOf('A')输出可以查看
吸取教训 希望下次代码可以更简洁。。
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
while (sc.hasNext()){
StringBuffer sb=new StringBuffer();
sb.append(sc.next());
String str=sb.reverse().substring(0,sb.length()-2);
char ch[]=str.toCharArray();
int sum=0;
for(int i=0;i<ch.length;i++){
if(ch[i]>='A'&&ch[i]<='F'){
sum+=(Integer.valueOf(ch[i])-55)*Math.pow(16,i);
}else {
sum+=(Integer.valueOf(ch[i])-48)*Math.pow(16,i);
}
}
System.out.println(sum);
}
}