蚂蚁爬杆

问题描述:

有一根27厘米的细木杆,在第3厘米、7厘米、11厘米、17厘米、23厘米这五个位置上各有一只蚂蚁。木杆很细,不能同时通过一只蚂蚁。开始时,蚂蚁的头朝左还是朝右是任意的,它们只会朝前走或调头,但不会后退。当任意两只蚂蚁碰头时,两只蚂蚁会同时调头朝反方向走。假设蚂蚁们每秒钟可以走一厘米的距离。编写程序,求所有蚂蚁都离开木杆的最小时间和最大时间。

解决方案:

网上有一种解法是这样的

public class Ants{
public static void main(String [] args){
Ants t= new Ants();
t.t1();
}
private void t1(){
Mayi a1=new Mayi();
Mayi a2=new Mayi();
Mayi a3=new Mayi();
Mayi a4=new Mayi();
Mayi a5=new Mayi();
for(int i=1;i<=2;i++){
for(int j=1;j<=2;j++){
for(int k=1;k<=2;k++){
for(int m=1;m<=2;m++){
for(int n=1;n<=2;n++){
a1.direct = i;
a1.site = 3;
a1.alreadygone=false;
a2.direct=j;
a2.site = 7;
a2.alreadygone=false;
a3.direct=k;
a3.site = 11;
a3.alreadygone=false;
a4.direct=m;
a4.site = 17;
a4.alreadygone=false;
a5.direct=n;
a5.site = 23;
a5.alreadygone=false;
for(int p=1;p<1000;p++){// 1.让蚂蚁走
if(!a1.alreadygone){
a1.step();
}
if(!a2.alreadygone){
a2.step();
}
if(!a3.alreadygone){
a3.step();
}
if(!a4.alreadygone){
a4.step();
}
if(!a5.alreadygone){
a5.step();
}
// 判断蚂蚁是否碰头
if(a1.site==a2.site&& a1.direct==2&&a2.direct==1){
a1.changeDirection();
a2.changeDirection();
}
if(a2.site==a3.site && a2.direct==2&&a3.direct==1){
a2.changeDirection();
a3.changeDirection();
}
if(a3.site==a4.site&&a3.direct==2&&a4.direct==1){
a3.changeDirection();
a4.changeDirection();
}
if(a4.site==a5.site &&a4.direct==2&&a5.direct==1){
a4.changeDirection();
a5.changeDirection();
}
//判断蚂蚁是否全部离开
if(a1.alreadygone &&a2.alreadygone &&a3.alreadygone &&a4.alreadygone &&a5.alreadygone){
System.out.println("over==="+p);
break;
}
}
}
}
}
}
}
}
}
class Mayi{ //用来表示蚂蚁所在的位置
public int site=0;//表示蚂蚁的朝向,1表示朝左,2表示朝右
public int direct=1;// 表示蚂蚁已经 离开木杆
public boolean alreadygone=false;// 蚂蚁的功能 // 蚂蚁走路
public void step(){
if(direct==1){
site=site-1;
}
else
site=site+1;
if(site==0||site==27){
alreadygone=true;
}
}// 蚂蚁掉头
public void changeDirection(){
if(direct==1)
direct=2;
else
direct=1;
}
}

其实此方法就是用递归的方法,实例化每一只蚂蚁,然后用for循环出每一种可能的初试移动方向的组合。然后找出最大值最小值。当然可以找出正确答案11和24但此方法的思路虽然简单明了一看就懂但过于麻烦后查找相关资料后得出另一种解题思路如下:

我们可以这样想,比如A,B两只蚂蚁A向左B向右相碰时各自掉头继续走,其实可以看做是A,B交换了身份,A看做是B,B看做是A,A继续向左走,B继续向又走,就好像根本没有相遇一样,继续走毫不影响,那这样就很明了了,最长时间就是所有蚂蚁离左右两端最远的距离,即27-3=24;而最短时间是所有蚂蚁距离左右两端的距离取最短的那段,分别是3,7,11,10,4;即所有蚂蚁最短时间走完所用的时间,待所有蚂蚁走完取最长的11,即本题的最短时间。代码如下:

public class AntTheme {
public static void main(String[] args) {
int[] pos = {3,7,11,17,23};//5只蚂蚁位置
int length = 27;//杆长
int mixRe = 0;//最短时间
int maxRe = 0;//最长时间 for (int i = 0; i < pos.length; i++) {//遍历所有蚂蚁
if (pos[i] <= length/2){//如果蚂蚁的位置居左边 /*则此蚂蚁爬出杆的最短时间就是向左走,即它的位置数,我们比较所有蚂蚁独自走出的最小时间,最长的那个才是所有蚂蚁走出的最短时间。
* 所以下面进行比较如果mixRe<pos[i]则mixRe=pos[i]
* */
if(mixRe<pos[i])
mixRe = pos[i];
/*此蚂蚁爬出杆的最长时间就是向右走,即杆长减去它的位置数,我们比较所有蚂蚁独自走出的最长时间,最长的那个才是所有蚂蚁都走出的最长时间。
* 所以下面进行比较如果maxRe<length-pos[i]则maxRe=length-pos[i]
* */
if(maxRe<length-pos[i])
maxRe = length-pos[i];
}else{//否则如果蚂蚁的位置居杆的右边
/*则此蚂蚁爬出杆的最短时间就是向右走,即它的杆长减去它位置数
* 以下同理
* */
if(mixRe<length-pos[i])
mixRe = length-pos[i];
/*则此蚂蚁爬出杆的最长时间就是向左走,即它的位置数
* 以下同理
* */
if(maxRe<pos[i])
maxRe = pos[i]; }
} System.out.println("做短时间为"+mixRe);
System.out.println("做长时间为"+maxRe);
}
}

输出同样是11和24。

字母金字塔

问题描述:

用ABCD在控制台输出对称金字塔,即第一行是A,第二行是BAB,第三行是CBABC...直到Z-A-Z

解决方案:
public class AbcTest {
public static void main(String[] args) {
for (int i = 1; i <27; i++) {//一共是27层,这里循环竖向的27行
for (int j = 0; j < 27-i; j++) {//再输出前方的空格
System.out.print(" ");
}
for (int k = i; k >0; k--) {//金字塔分两侧输出,一侧是倒写的
System.out.print((char)(64+k));
}
for (int h = 1; h < i; h++) {//一侧是正写的
System.out.print((char)(65+h));
}
System.out.println();//换行
}
}
}


这个基本没什么难度,关键了解字母对应ASCII的值。

Java输出杨辉三角

问题描述:

杨辉三角大家都知道,端点的数为1。每个数等于它上方两数之和。每行数字左右对称,由1开始逐渐变大。第n行的数字有n项。如下图:用Java打印输出

解决方案:

此处主要用到的是二维数组,代码如下:

import java.util.Scanner;

public class YangHuiTriangle {
public static void main(String[] args) { //有控制台得到要输出的行数
System.out.println("请输入杨辉三角的行数:");
Scanner ScRows=new Scanner(System.in);
final int Rows=ScRows.nextInt(); //声明二维数组,用二维数组的一位表示行数,二维表示此行的数字
int array[][] =new int[Rows][]; //循环初始化数组的二维
for(int i=0;i<Rows;i++){
array[i]=new int[i+1];//每一行的数字个数等于行数
} System.out.println("杨辉三角为:");
YhTriangle(array,Rows);
} //输出杨辉三角
public static void YhTriangle(int array[][], int rows) {
//行控制
for(int i=0;i<rows;i++){
//列控制
for(int j=0;j<array[i].length;j++){
/*当i为0或者j为0时,即第一行和每行的开头时,或者j==array[i].length-1即到达该行的结尾时
* 赋值给二位数组,将两边的元素赋值为1
* */
if(i==0||j==0||j==array[i].length-1)
array[i][j]=1;
//否则将其正上方元素与左上角元素之和赋值给此元素中。
else
array[i][j]=array[i-1][j-1]+array[i-1][j];
}
}
//打印输出杨辉三角
for(int i=0;i<rows;i++){
//打印左侧空格
for (int p = 0; p < rows-i; p++) {
System.out.print(" ");
}
//循环输出数组的每行
for(int j=0;j<array[i].length;j++){
System.out.print(array[i][j]+" ");
}
System.out.println();
}
}
}

字符串取相同字符

问题描述:

字符串a,b,打印出字符串a,b中的所有相同字符;

解决方案:
import java.util.HashSet;
public class windowsTest {
public static void main(String[] args) {
HashSet<String> set = new HashSet<String>();
String s1 = "1234地方方5";
String s2 = "23d456"; for (int i = 0; i < s1.length(); i++) {
set.add(String.valueOf(s1.charAt(i)));
} for(int i = 0; i < s2.length(); i++){
if(!set.add(String.valueOf(s2.charAt(i))))
System.out.print(s2.charAt(i));
}
}
}

这里的要点是用到了HashSet,先将s1的字符串转为char存入set,HashSet中不允许有重复的元素,HashSet插入的方法add()API解释如下如果此 set 中尚未包含指定元素,则添加指定元素。更确切地讲,如果此 set 没有包含满足(e==null ? e2==null : e.equals(e2)) 的元素e2,则向此 set 添加指定的元素e。如果此 set 已包含该元素,则该调用不更改 set 并返回false。所以我们根据s2按字符插入时返回的true or false判断s1是否包含,从而得出s1,s2的相同字符。
关于HashSet,TreeMap的区别摘抄如下:

1. HashSet是通过HashMap实现的,TreeSet是通过TreeMap实现的,只不过Set用的只是Map的key

2. Map的key和Set都有一个共同的特性就是集合的唯一性.TreeMap更是多了一个排序的功能.

3. hashCode和equal()是HashMap用的, 因为无需排序所以只需要关注定位和唯一性即可.

a. hashCode是用来计算hash值的,hash值是用来确定hash表索引的.

b. hash表中的一个索引处存放的是一张链表, 所以还要通过equal方法循环比较链上的每一个对象 才可以真正定位到键值对应的Entry.

c. put时,如果hash表中没定位到,就在链表前加一个Entry,如果定位到了,则更换Entry中的value,并返回旧value

4. 由于TreeMap需要排序,所以需要一个Comparator为键值进行大小比较.当然也是用Comparator定位的.

a. Comparator可以在创建TreeMap时指定

b. 如果创建时没有确定,那么就会使用key.com

字符串取出现次数最多字符

问题描述:

给出一个字符串如“abdbbbbccefg”,返回此字符串中出现最多的字母。此例即返回b

解决方案:
public class Testabc {
public static void main(String[] args){
String str = "aabbbbbbbbbcccdffff"; char[] abc = new char[26];
for(int i=0;i<str.length();i++)
abc[str.charAt(i)-'a']++; int maxtimes = 0;
char res = 0;
for(int i=0;i<26;i++)
if(abc[i]>maxtimes) {
maxtimes=abc[i];
res=(char)('a'+i);
}
System.out.println("出现次数最多的为字母"+res+"出现次数"+maxtimes);
}
}

首先是声明了一个char[]数组abc用来存贮26个字母分别出现的次数,关键理解

abc[str.charAt(i)-'a']++;

此for循环遍历str的每个字符,如遍历第一个时是str.charAt(1),取到的是字符‘a',a在此强制转为int的话是ASCII码值97,而abc数组的长度是26个字符,所有让读取到的每个字符去减去’a',则a到z出现的次数分别存储到了abc[0]到abc[25]中,下面就不用解释了,再循环遍历abc[]取出值最大的即出现次数最多的,在哪个位置取出的再加上‘a'就还原了原本的字母。

JAVA输出日历

问题描述:

从控制台得到输入的年份,月份,输出此年此月的日历。

解决方案:
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.Scanner; public class MyDateShow { public static void showCalendar(int year,int month){
GregorianCalendar gc = new GregorianCalendar(year,month-1,1);//构造日期 int week = gc.get(Calendar.DAY_OF_WEEK);//得此日这天是周几
int days = gc.getActualMaximum(Calendar.DATE);//得到此月份有多少天 System.out.println("日\t一\t二\t三\t四\t五\t六"); for (int i = 1; i < week; i++) {
System.out.print(" \t");
} for (int i = 1; i <=days; i++) {
System.out.print(i+"\t");
if(i%7==7-week+1){
System.out.println();
}
} } public static void main(String[] args) {
System.out.println("请输入年份空格加月份:(如“2013 8”)");
Scanner sc = new Scanner(System.in); int year = sc.nextInt();
int month = sc.nextInt(); System.out.println("将要输出的日历为"+year+"年"+month+"月"); showCalendar(year,month);
} }

GregorianCalendar是java.util.Calendar的一个具体子类,提供了世界上大多数国家/地区使用的标准日历系统。

GregorianCalendar(int year, int month, int dayOfMonth) 
        在具有默认语言环境的默认时区内构造一个带有给定日期设置的 GregorianCalendar。以此构造方法,用输入的年份,月份,加上自定义的日期1,构造出此年此月1号gc值得注意的是JAVA常量字段值里1月用0表示,2月是1,一次类推,所以构造日期时是输入的month-1

然后我们用

int week = gc.get(Calendar.DAY_OF_WEEK);

int days = gc.getActualMaximum(Calendar.DATE);

分别得到此月1号是周几,此月的天数,就可以循环打印出日历了。首先打印出日历的星期行,一般把周日放第一个(“\t”代表tab键)。然后换行,输出1号前面的空格,1号前面有几个空格要看1号是周几,JAVA常量字段值里周日是1,周一是2,周二是3,依次到周五是6,周六是7,那就是说如果1号得到是周四,得到的week则是5,按‘日’,‘一’,‘二’,‘三’,‘四’,‘五’,‘六’排列则前面应该输出4个空格加tab。即

for (int i = 1; i < week; i++) 

输出完空格后就开始循环输出1号到此月的最后一天。此月有days天则输出days个数,即

for (int i = 1; i <=days; i++) 

然后是判断在几号时换行,按所有输入,都是7个格子换一行,首先看第一行,1号前面已经空了week-1个格,那再加7-(week-1)个格子时换行,后面每行的各自数都是7的倍数,所以用表达式i%7==7-week+1来判断是否换行。就这样输出整个日历

再有在控制台输入读取数据的方法我另有一篇博客介绍大家可以看看,Scanner的next()方法默认是用空格坐分隔符读取下一个输入值,nextInt()则读取返回int,所以控制台输入时要求输入年份加空格加月份,方便读取。最终效果如图:

整理自百度知道提问的几道Java编程题的更多相关文章

  1. 50道经典的JAVA编程题 (16-20)

    50道经典的JAVA编程题 (16-20),用了快一个下午来做这10道题了,整理博客的时间貌似大于编程的时间啊..哈哈 [程序16]Nine.java 题目:输出9*9口诀. 1.程序分析:分行与列考 ...

  2. 50道经典的JAVA编程题(汇总)

    这是一次不可思议的编程历程.从2013年的最后一天开始做这份题,中间连续好几天的考试,包括java考试(今天考试的JAVA编程题),直到今天完成了.挺有成就感的...废话不多说了,来电实质性的吧. 全 ...

  3. 50道经典的JAVA编程题(46-50)

    50道经典的JAVA编程题(46-50),最后五道题了,这是一个美妙的过程,编程真的能让我忘掉一切投入其中,感觉很棒.今天下午考完微机原理了,大三上学期就这样度过了,这学期算是解放了,可是感觉我还是没 ...

  4. 50道经典的JAVA编程题(41-45)

    50道经典的JAVA编程题(41-45),苦逼的程序猿,晚上睡不着了编程吧~今天坚持做10道题!发现编程能是我快乐...O(∩_∩)O哈哈~能平静我烦乱的心,剩下5道题留到考试完了再做吧!该睡觉了.. ...

  5. 50道经典的JAVA编程题(36-40)

    50道经典的JAVA编程题(36-40),今天晚上心情压抑,不爽,继续做题,管它明天考试,我继续我的java,一个周末都在看微机原理看得的很头疼啊~明天该挂科就挂吧,不在乎了~~~ [程序36] Ar ...

  6. 50道经典的JAVA编程题(31-35)

    50道经典的JAVA编程题(31-35),今天考完了java,在前篇博客里面贴出了题了,见:<今天考试的JAVA编程题>.考完了也轻松了,下个星期一还考微机原理呢,啥都不会,估计今天就做到 ...

  7. 50道经典的JAVA编程题(26-30)

    50道经典的JAVA编程题(26-30),这么晚了,早点睡了要,明早8点考java祝我好运吧!!!晚安~ [程序26]Ex26.java(跳过了,好没意思的题啊)题目:请输入星期几的第一个字母来判断一 ...

  8. 50道经典的JAVA编程题(21-25)

    50道经典的JAVA编程题(21-25),明天早上java考试了,还是坚持做题吧...这题比老师的题好多了! [程序21]TestJieCheng.java题目:求1+2!+3!+...+20!的和1 ...

  9. 50道经典的JAVA编程题 (11-15)

    50道经典的JAVA编程题 (11-15),新年的第一天,继续啦...\(^o^)/~,这50道题都跨年了啊...哈哈 [程序11] TestTN.java 题目:有1.2.3.4个数字,能组成多少个 ...

随机推荐

  1. Linux下安装配置词典GoldenDict

    GoldenDict   apt-get install goldendict 安装完成以后,需要自己手动加入字典,增加在线翻译网址(例如,有道,金山等),点击 编辑--dictionaries  完 ...

  2. Dynamic Pivot table wizard SQL Server

    原文 http://www.gyurcit.hu/pivot.html Dynamic Pivot table wizard This stored procedure generate dynami ...

  3. sql和shell注入测试

    1.整数型参数,必须intval转义,用addslashes转义不行 <?php   $test = $_REQUEST["test"]; $test = addslashe ...

  4. Linux下搭建Hadoop具体步骤

    装好虚拟机+Linux.而且主机网络和虚拟机网络互通. 以及Linux上装好JDK 1:在Linux下输入命令vi /etc/profile 加入HADOOP_HOME export JAVA_HOM ...

  5. 【linux】开发环境说明

    欢迎转载,转载时请保留作者信息,谢谢. 邮箱:tangzhongp@163.com 博客园地址:http://www.cnblogs.com/embedded-tzp Csdn博客地址:http:// ...

  6. MFC拆分窗口及它们之间的数据交换

    源代码:http://download.csdn.net/detail/nuptboyzhb/4221531 CSplitterWnd类 CSplitterWnd类提供一个分隔器窗口的功能,分隔器窗口 ...

  7. Servlet的学习之Request请求对象(3)

    本篇接上一篇,将Servlet中的HttpServletRequest对象获取RequestDispatcher对象后能进行的[转发]forward功能和[包含]include功能介绍完. 首先来看R ...

  8. Delphi安装NT服务程序时(不出现提示信息)

    如果我们不加上"/silent",那么Delphi在安装和卸载NT服务程序时候,都会出现一个提示信息,不希望出现这个提示信息,那么使用如下命令: 1,安装:“你的nt程序 /ins ...

  9. [概念] js的函数节流和throttle和debounce详解

    js的函数节流和throttle和debounce详解:同样是实现了一个功能,可能有的效率高,有的效率低,这种现象在高耗能的执行过程中区分就比较明显.本章节一个比较常用的提高性能的方式,通常叫做&qu ...

  10. FOJ 1607 Greedy division 数学题

    题目地址: http://acm.fzu.edu.cn/problem.php?pid=1607 给定一个n,将n平均分成m份,问有几种方法,每种方法中找出最大的数.思路:就是求n的因子数.先将每个数 ...