三個java超級變態邏輯迴圈程式設計題
1:有一根27釐米的細木杆,在第3釐米、7釐米、11釐米、17釐米、23釐米這五個位置上各有一隻螞蟻。木杆很細,不能同時通過一隻螞蟻。開始時,螞蟻的頭朝左還是朝右是任意的,它們只會朝前走或調頭,但不會後退。當任意兩隻螞蟻碰頭時,兩隻螞蟻會同時調頭朝反方向走。假設螞蟻們每秒鐘可以走一釐米的距離。編寫程式,求所有螞蟻都離開木杆的最小時間和最大時間
import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.Set; /** * <pre> * <strong>説明.</strong> * 有一根27釐米的細木杆,在第3釐米、7釐米、11釐米、17釐米、23釐米這五個位置上各有一隻螞蟻。 * 木杆很細,不能同時通過一隻螞蟻。 * 開始時,螞蟻的頭朝左還是朝右是任意的,它們只會朝前走或調頭,但不會後退。 * 當任意兩隻螞蟻碰頭時,兩隻螞蟻會同時調頭朝反方向走。 * 假設螞蟻們每秒鐘可以走一釐米的距離。 * 編寫程式,求所有螞蟻都離開木杆的最小時間和最大時間。 * </pre> * * <pre> * <strong>注意事項:</strong> * </pre> * * <pre> * <strong>使用例:</strong> * </pre> */ public class TestDemo29 { /** 全域性變數:存放所有組合*/ private static Set<String> set = new HashSet<String>(); /** 所有方向組合的螞蟻*/ private static List<Map> staticList = new ArrayList<Map>(); /** * @param args */ public static void main(String[] args) { List<Mayi> mayiList = getInitDat(); List<String> list = new ArrayList<String>(); Mayi mayi; try { // 獲得所有螞蟻的編號 for (int i = 0; i < mayiList.size(); i++) { mayi = mayiList.get(i); list.add(mayi.getNo()); } // 將螞蟻編號放入list通過doList方法決定他們的初始方向 for (int i = 0; i <= list.size(); i++) { doList(list, i); } String zidx = ""; int idx; for (Iterator<String> it = set.iterator(); it.hasNext();) { zidx = it.next(); mayiList = getInitDat(); char[] ca = zidx.toCharArray(); for (char c : ca) { idx = Integer.parseInt(String.valueOf(c)) - 1; mayi = mayiList.get(idx); mayi.setStaFx(1); mayiList.remove(idx); mayiList.add(idx, mayi); } staticList.add(doWay(mayiList)); } // 做完上面這些我們已經的出每一種方向組合和他們離開木杆所用的時間 // 接下來只需要比較他們的時間大小便可 Map map = new HashMap(); int maxTime = Integer.parseInt(staticList.get(0).get("count").toString()); int minTime = maxTime; for (Iterator<Map> it = staticList.iterator(); it.hasNext();) { map = it.next(); int nowTime = Integer.parseInt(map.get("count").toString()); if (nowTime > maxTime) { maxTime = nowTime; } else if (minTime > nowTime) { minTime = nowTime; } } System.out.println(maxTime); System.out.println(minTime); // 上面已經的得到了最小和最大的時間,程式在這裡就可以結束了。如果要得到對應的螞蟻初始狀態可以用下面的方法 for (Iterator<Map> it = staticList.iterator(); it.hasNext();) { map = it.next(); if (maxTime == Integer.parseInt(map.get("count").toString())) { System.out.println("最大時間:" + maxTime + "。螞蟻初始狀態是:" +map.get("putInitSta").toString()); } if (minTime == Integer.parseInt(map.get("count").toString())) { System.out.println("最小時間:" + minTime + "。螞蟻初始狀態是:" +map.get("putInitSta").toString()); } } } catch (IndexOutOfBoundsException ioe) { System.out.println("陣列越界"); } catch (Exception e) { e.printStackTrace(); } } /** * <TT><pRE> * <p> 定義一個螞蟻類. 其中三個引數no:螞蟻編號、staXy:座標、staFx:方向.</p> * @author wangguanquan *</PRE></TT> */ static class Mayi { private String no; // 5只螞蟻的編號 private int staXy; // 當前座標(距離近點的距離) private int staFx = -1; // 當前方向,設定初始方向為負(朝向近點為負,背向近點為正) /** * @return 編號 */ public String getNo() { return no; } /** * @param 編號 設定する no */ public void setNo(String no) { this.no = no; } /** * @return 方向 */ public int getStaFx() { return staFx; } /** * @param 方向 設定する staFx */ public void setStaFx(int staFx) { this.staFx = staFx; } /** * @return 當前座標 */ public int getStaXy() { return staXy; } /** * @param 當前座標 設定する staXy */ public void setStaXy(int staXy) { this.staXy = staXy; } } /** * <TT><pRE> * <p> 取得5只螞蟻的初始資料.</p> * @return list * </PRE></TT> */ protected static List<Mayi> getInitDat() { List<Mayi> list = new ArrayList<Mayi>(); Mayi mayi = new Mayi(); mayi.setNo("1"); mayi.setStaXy(3); list.add(mayi); mayi = new Mayi(); mayi.setNo("2"); mayi.setStaXy(7); list.add(mayi); mayi = new Mayi(); mayi.setNo("3"); mayi.setStaXy(11); list.add(mayi); mayi = new Mayi(); mayi.setNo("4"); mayi.setStaXy(17); list.add(mayi); mayi = new Mayi(); mayi.setNo("5"); mayi.setStaXy(23); list.add(mayi); return list; } /** * <TT><pRE> * <p> 採用回溯法找出定長度所有可能的組合.</p> * @param list 所有螞蟻 * @param len 個數 * @return List 指定個數所有可能的組合 * @throws Exception 例外 * </PRE></TT> */ protected static List doList(List list, int len) throws Exception { List<String> lst = new ArrayList<String>(); StringBuffer sb = null; int begIdx = 0; if (len == 0) { set.add(""); return list; } if (len == 1) { for (Iterator it = list.iterator(); it.hasNext();) { set.add(it.next().toString()); } return list; } while (begIdx < list.size() - len + 1) { sb = new StringBuffer(); sb.append(list.get(begIdx)); List typeLst = doList(list.subList(begIdx + 1, list.size()), len - 1); for (int i = 0; i < typeLst.size(); i++) { sb.append(typeLst.get(i)); lst.add(sb.toString()); set.add(sb.toString()); sb.delete(1, sb.length()); } begIdx++; } return lst; } /** * <TT><pRE> * <p> 根據條件移動木棍上的每一隻螞蟻.並計算移動時間</p> * @param Map 返回組合和每種組合所用的時間 * @throws Exception 例外 * </PRE></TT> */ protected static Map doWay(List<Mayi> list) throws Exception { Map map = new HashMap(); StringBuffer sb = new StringBuffer(); int count = 0; Mayi mayi = null; int staXy; for (int i = 0; i < list.size(); i++) { sb.append(list.get(i).staFx); sb.append(", "); sb.append(list.get(i).staXy); sb.append("|"); } // /////////////////////////////測試程式碼,觀察螞蟻的初期情況///////////////////////////// // System.out.println(sb.toString()); // System.out.println("<------------" + count +"----------->"); // ////////////////////////////////////////////////////////////////////////////////// map.put("putInitSta", sb.toString()); List<Mayi> reFxList = reSetFx(list); // 無限迴圈直到所有螞蟻離開木杆 while (!win(reFxList)) { for (int i = 0; i < reFxList.size(); i++) { mayi = reFxList.get(i); // 如果螞蟻走出木棍將不進行移動 if (mayi.getStaXy() == 0 || mayi.getStaXy() == 27) { continue; } // 移動在木棍上的螞蟻 staXy = mayi.getStaXy() + mayi.getStaFx(); mayi.setStaXy(staXy); reFxList.remove(i); reFxList.add(i, mayi); } // 同一時間每隻螞蟻都在移動所以count++放在迴圈外,如果想知道一共移動了多少釐米將count++放在迴圈體內便可 count++; // /////////////////////////測試程式碼,觀察螞蟻的每一步的移動情況///////////////////////// // for (int i = 0; i < reFxList.size(); i++) { // System.out.println(reFxList.get(i).staFx + "|" + reFxList.get(i).staXy); // } // System.out.println(">------------" + count +"-----------<"); // ////////////////////////////////////////////////////////////////////////////////// reFxList = reSetFx(reFxList); } map.put("count", count); return map; } /** * <TT><pRE> * <p> 判斷所有螞蟻是否走出木棍.</p> * @param list * @return * </PRE></TT> */ protected static boolean win(List<Mayi> list) { Mayi mayi = null; for (int i = 0; i < list.size(); i++) { mayi = list.get(i); if (mayi.getStaXy() != 0 && mayi.getStaXy() != 27) { return false; } } return true; } /** * <TT><pRE> * <p> 任意兩隻螞蟻碰頭時的方向處理.</p> * @param list 碰頭前的隊伍 * @return list 碰頭後的隊伍 * @throws Exception 例外 * </PRE></TT> */ protected static List<Mayi> reSetFx(List<Mayi> list) throws Exception { Mayi mayi = null; int idx = 0; while (idx < list.size() - 1) { mayi = list.get(idx); // 如果螞蟻走出木棍將不進行調頭 if (mayi.getStaXy() == 0 || mayi.getStaXy() == 27) { idx++; continue; } int nidx = idx + 1; Mayi mayix = list.get(nidx); // 當任意兩隻螞蟻碰頭時,兩隻螞蟻同時調頭朝反方向走。 if (mayi.getStaXy() == mayix.getStaXy()) { mayi.setStaFx(mayi.getStaFx() * -1); mayix.setStaFx(mayix.getStaFx() * -1); list.remove(idx); list.add(idx, mayi); list.remove(nidx); list.add(nidx, mayix); } idx++; } return list; } }
測試結果:最大時間:24。螞蟻初始狀態是:1, 3|-1, 7|1, 11|1,17|-1, 23|最大時間:24。螞蟻初始狀態是:1, 3|-1, 7|1, 11|-1,17|1, 23|最大時間:24。螞蟻初始狀態是:1, 3|-1, 7|-1,11|-1, 17|1, 23|最大時間:24。螞蟻初始狀態是:1, 3|-1, 7|1, 11|-1,17|-1, 23|最大時間:24。螞蟻初始狀態是:1, 3|-1, 7|-1, 11|1,17|-1, 23|最大時間:24。螞蟻初始狀態是:1, 3|1, 7|-1, 11|-1,17|-1, 23|最大時間:24。螞蟻初始狀態是:1, 3|1, 7|-1, 11|1,17|1, 23|
// 1, 3|1, 7|1, 11|-1, 17|1, 23 可以這麼看:第一位是方向,第二位是螞蟻的初始位置, “|” 各開每一隻螞蟻,假設5只螞蟻都在X座標上移動,往正方向移動那麼方向為1,相反負方向移動方向為-1
2:參加會議:有人邀請A,B,C,D,E,F6個人參加一項會議,這6個人有些奇怪,因為他們有很多要求,已知:
(1).A,B兩人至少有1人蔘加會議。
(2).A,E,F3人中有2人蔘加會議。
(3).B和C兩人一致決定,要麼兩人都去,要麼兩人都不去。
(4).A,D兩人中只1人蔘加會議。
(5).C,D兩人中也只要1人蔘加會議。
(6).如果D不去,那麼E也決定不去。那麼最後究竟有哪幾個人蔘加了會議呢?
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
public class TestDemo28 {
/** 全域性變數:存放所有組合*/
private static Set<String> set = new HashSet<String>();
/**
* @param args
*/
public static void main(String[] args) {
// 用一個List存放所有參會人員
List<String> preList = new ArrayList<String>();
preList.add("A");
preList.add("B");
preList.add("C");
preList.add("D");
preList.add("E");
preList.add("F");
try {
// 得到所有的組合
for (int i = 1; i <= preList.size(); i++) {
doList(preList, i);
}
// 判斷每一種組合是否符合條件
for (Iterator<String> it = set.iterator(); it.hasNext();) {
marc(it.next().toString());
}
} catch (IndexOutOfBoundsException ioe) {
System.out.println("陣列越界");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* <TT><PRE>
* <p>參加會議:有人邀請A,B,C,D,E,F6個人參加一項會議.</p>
* @param sb 引數:A,B,C,D,E,F6個人的某種組合
* @return boolean true:符合條件 false:不符合條件
*</PRE></TT>
*/
protected static boolean marc(String sb) {
// (1).A,B兩人至少有1人蔘加會議。
if (!sb.contains("A") && !sb.contains("B")) {
return false;
}
// (2).A,E,F3人中有2人蔘加會議。
if (!((sb.contains("A") && sb.contains("E"))
|| (sb.contains("A") && sb.contains("F"))
|| (sb.contains("E") && sb.contains("F")))) {
return false;
}
// (3).B和C兩人一致決定,要麼兩人都去,要麼兩人都不去。
if ((sb.contains("B") && !sb.contains("C"))
|| (!sb.contains("B") && sb.contains("C"))) {
return false;
}
// (4).A,D兩人中只1人蔘加會議。
if (sb.contains("A") && sb.contains("D")) {
return false;
}
// (5).C,D兩人中也只要1人蔘加會議。
if (sb.contains("C") && sb.contains("D")) {
return false;
}
// (6).如果D不去,那麼E也決定不去。
if (!sb.contains("D") && sb.contains("E")) {
return false;
}
// 輸出滿足條件的組合
System.out.println(sb);
return true;
}
/**
* <TT><PRE>
* <p> 採用回溯法找出制定長度所有可能的組合.</p>
* @param list 所有候選人
* @param len 個數
* @return List 指定人數所有可能的組合
* @throws Exception 例外
* </PRE></TT>
*/
protected static List doList(List list, int len) throws Exception {
List<String> lst = new ArrayList<String>();
StringBuffer sb = null;
int begIdx = 0;
if (len == 1) {
for (Iterator it = list.iterator(); it.hasNext();) {
set.add(it.next().toString());
}
return list;
}
while (begIdx < list.size() - len + 1) {
sb = new StringBuffer();
sb.append(list.get(begIdx));
List typeLst = doList(list.subList(begIdx + 1, list.size()), len - 1);
for (int i = 0; i < typeLst.size(); i++) {
sb.append(typeLst.get(i));
lst.add(sb.toString());
set.add(sb.toString());
sb.delete(1, sb.length());
}
begIdx++;
}
return lst;
}
3:用程式求解:請回答下面10個問題:1、第一個答案是b的問題是哪一個? (a)2;(b) 3;(c)4;(d)5;(e)6 2、唯一的連續兩個具有相同答案的問題是: (a)2,3;(b)3,4;(c)4,5;(d)5,6;(e)6,7;3、本問題答案和哪一個問題的答案相同? (a)1;(b)2;(c)4;(d)7;(e)6 4、答案是a的問題的個數是: (a)0;(b)1;(c)2;(d)3;(e)4 5、本問題答案和哪一個問題的答案相同? (a)10;(b)9;(c)8;(d)7;(e)6 6、答案是a的問題的個數和答案是什麼的問題的個數相同? (a)b;(b)c;(c)d;(d)e;(e)以上都不是7、按照字母順序,本問題的答案和下一個問題的答案相差幾個字母? (a)4;(b)3;(c)2;(d)1;(e)0 (注:a和b相差一個字母)8、答案是母音字母的問題的個數是: (a)2;(b)3;(c)4;(d)5;(e)6 (注:a和e是母音字母)9、答案是子音字母的問題的個數是: (a)一個質數;(b)一個階乘數;(c)一個平方數;(d)一個立方數,(e)5的倍數10、本問題的答案是: (a)a;(b)b;(c)c;(d)d;(e)e
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
/**
* @author bree06
*
*/
public class Demo9 {
public static final char DEFAULTCHAR = 'a';
public static final String DEFAULTSTR_A = "a";
public static final String DEFAULTSTR_B = "b";
public static final String DEFAULTSTR_E = "e";
public static List<String[]> list = null;
private static String allAnswer = null;
/**
* @param args
*/
public static void main(String[] args) {
long start = System.currentTimeMillis();
init();
StringBuilder answer = new StringBuilder();
answer.append("aaaaaaaaaa");
File file = new File("e:/allanswer.txt");
FileWriter writer = null;
try {
if (!file.exists()) {
file.createNewFile();
}
writer = new FileWriter(file);
for (char i = 'a'; i <= 'e'; i++) {
answer.deleteCharAt(0);
answer.insert(0, i);
for (char j = 'a'; j <= 'e'; j++) {
answer.deleteCharAt(1);
answer.insert(1, j);
for (char m = 'a'; m <= 'e'; m++) {
answer.deleteCharAt(2);
answer.insert(2, m);
for (char n = 'a'; n <= 'e'; n++) {
answer.deleteCharAt(3);
answer.insert(3, n);
for (char a = 'a'; a <= 'e'; a++) {
answer.deleteCharAt(4);
answer.insert(4, a);
for (char b = 'a'; b <= 'e'; b++) {
answer.deleteCharAt(5);
answer.insert(5, b);
for (char c = 'a'; c <= 'e'; c++) {
answer.deleteCharAt(6);
answer.insert(6, c);
for (char d = 'a'; d <= 'e'; d++) {
answer.deleteCharAt(7);
answer.insert(7, d);
for (char e = 'a'; e <= 'e'; e++) {
answer.deleteCharAt(8);
answer.insert(8, e);
for (char f = 'a'; f <= 'e'; f++) {
answer.deleteCharAt(9);
answer.insert(9, f);
allAnswer = answer.toString();
if (matcher()) writer.write(allAnswer + "\n");
}
}
}
}
}
}
}
}
}
}
writer.write("total time: (ms)" + (System.currentTimeMillis() - start));
} catch (IOException e) {
try {
writer.write(e.getMessage());
} catch (IOException e1) {}
e.printStackTrace();
} finally {
try {
if (writer != null)
writer.close();
} catch (IOException e) {}
}
}
/**
* 初始化所有問題的答案
*/
private static void init() {
list = new ArrayList<String[]>();
list.add(new String[]{"2", "3", "4", "5", "6"});
list.add(new String[]{"2,3", "3,4", "4,5", "5,6", "6,7"});
list.add(new String[]{"1", "2", "4", "7", "6"});
list.add(new String[]{"0", "1", "2", "3", "4"});
list.add(new String[]{"10", "9", "8", "7", "6"});
list.add(new String[]{"b", "c", "d", "e", "a"});
list.add(new String[]{"4", "3", "2", "1", "0"});
list.add(new String[]{"2", "3", "4", "5", "6"});
list.add(new String[]{"a", "b", "c", "d", "e"});
list.add(new String[]{"a", "b", "c", "d", "e"});
}
private static boolean matcher() {
return (No1() && No2() && No3() && No4() && No5() && No6() && No7() && No8() && No9());
}
/**
* 1、第一個答案是b的問題是哪一個?
* @return
*/
private static boolean No1() {
return ((allAnswer.indexOf(DEFAULTSTR_B) + 1) == Integer.parseInt(list.get(0)[getThisAns(1)]));
}
/**
* 2、唯一的連續兩個具有相同答案的問題是:
* @return
*/
private static boolean No2() {
int cnt = 0, idx = 0;
while (idx < allAnswer.length() - 1) {
if (allAnswer.charAt(idx) == allAnswer.charAt(++idx)) {
cnt++;
}
}
if (cnt != 1) return Boolean.FALSE;
String ans = list.get(1)[getThisAns(2)];
return (allAnswer.charAt(Integer.parseInt(ans.split(",")[0])-1) == allAnswer.charAt(Integer.parseInt(ans.split(",")[1])-1));
}
/**
* 3、本問題答案和哪一個問題的答案相同?
* @return
*/
private static boolean No3() {
return ((allAnswer.charAt(Integer.parseInt(list.get(2)[getThisAns(3)]) - 1) - DEFAULTCHAR) == getThisAns(3));
}
/**
* 4、答案是a的問題的個數是:
* @return
*/
private static boolean No4() {
return (Integer.parseInt(list.get(3)[getThisAns(4)]) == contChar(allAnswer, DEFAULTSTR_A));
}
/**
* 5、本問題答案和哪一個問題的答案相同?
* @return
*/
private static boolean No5() {
return ((allAnswer.charAt(Integer.parseInt(list.get(4)[getThisAns(5)]) - 1) - DEFAULTCHAR) == getThisAns(5));
}
/**
* 6、答案是a的問題的個數和答案是什麼的問題的個數相同?
* @param thisAns
* @param allAnswer
* @return
*/
private static boolean No6() {
return (contChar(allAnswer, DEFAULTSTR_A) == contChar(allAnswer, list.get(5)[getThisAns(6)]));
}
/**
* 7、按照字母順序,本問題的答案和下一個問題的答案相差幾個字母?
* @return
*/
private static boolean No7() {
return (Math.abs(allAnswer.charAt(6)-allAnswer.charAt(7)) == Integer.parseInt(list.get(6)[getThisAns(7)]));
}
/**
* 8、答案是母音字母的問題的個數是:
* @return
*/
private static boolean No8() {
int cntae = contChar(allAnswer, DEFAULTSTR_A) + contChar(allAnswer, DEFAULTSTR_E);
return (Integer.parseInt(list.get(7)[getThisAns(8)]) == cntae);
}
/**
* 9、答案是子音字母的問題的個數是:
* (a)一個質數;(b)一個階乘數;(c)一個平方數;(d)一個立方數,(e)5的倍數;
* @return
*/
private static boolean No9() {
int cntbcd = allAnswer.length() - contChar(allAnswer, DEFAULTSTR_A) - contChar(allAnswer, DEFAULTSTR_E);
switch (getThisAns(9)) {
case 0:
return (String.valueOf(cntbcd).matches("[2357]"));
case 1:
return (String.valueOf(cntbcd).matches("[026]"));
case 2:
return (String.valueOf(cntbcd).matches("[149]"));
case 3:
return (String.valueOf(cntbcd).matches("[18]"));
case 4:
return (cntbcd % 5 == 0);
default:
return Boolean.FALSE;
}
}
/**
* 計算字串中有多少個指定字元
* @param str
* @param chr
* @return
*/
public static int contChar(String str, String chr) {
if (str == null || "".equals(str)) return 0;
return (str.length() - str.replace(chr, "").length());
}
/**
* 取得本題答案
* @param index 題號
* @return
*/
public static int getThisAns(int index) {
index = index > allAnswer.length() ? allAnswer.length() - 1 : index - 1;
return allAnswer.charAt(index) - DEFAULTCHAR;
}
}
//
滿足條件的組合有:abddaedcba
cdebeeaece
cdebeedcba