21. 古堡算式
/*
福爾摩斯到某古堡探險,看到門上寫着一個奇怪的算式:
ABCDE * ? = EDCBA
他對華生說:「ABCDE應該表明不一樣的數字,問號也表明某個數字!」
華生:「我猜也是!」
因而,兩人沉默了很久,仍是沒有算出合適的結果來。
請你利用計算機的優點,找到破解的答案。
把 ABCDE 所表明的數字寫出來。
答案寫在「解答.txt」中,不要寫在這裏!
*/
public class TDemo02_two {
public static void main(String[] args){
for(int i=10000;i<100000;i++){
int a = i/10000;
int b = i%10000/1000;
int c = i%10000%1000/100;
int d = i%10000%1000%100/10;
int e = i%10;
if(a==b||a==c||a==d||a==e||b==c||b==d||b==e||c==d||c==e||d==e){
continue;
}
int y = e*10000+d*1000+c*100+b*10+a;
if(y%i==0){
System.out.println(i+"*"+y/i+"="+y);
}
}
}
}
運行結果:
21978*4=87912
22. 微生物增殖
/*
假設有兩種微生物 X 和 Y
X出生後每隔3分鐘分裂一次(數目加倍),Y出生後每隔2分鐘分裂一次(數目加倍)。
一個新出生的X,半分鐘以後吃掉1個Y,而且,今後開始,每隔1分鐘吃1個Y。
如今已知有新出生的 X=10, Y=89,求60分鐘後Y的數目。
若是X=10,Y=90 呢?
本題的要求就是寫出這兩種初始條件下,60分鐘後Y的數目。
題目的結果令你震驚嗎?這不是簡單的數字遊戲!真實的生物圈有着一樣脆弱的性質!也許由於你消滅的那隻 Y 就是最終致使 Y 種羣滅絕的最後一根稻草!
請忍住悲傷,把答案寫在「解答.txt」中,不要寫在這裏!
*/
package Question20_29;
import java.util.Scanner;
public class Question22MustRemember {
public static void calculate(int primaryNumX,int primaryNumY,int timesOfMinute) {
int numX=primaryNumX,numY=primaryNumY;
for (int i = 2; i <=timesOfMinute*2; i++) {
if(numY<=0){
numY=0;
break;
}
if(i%2==0){
numY-=primaryNumX;// 當爲整數分鐘時,最初數目的生物X將進食同等數目的生物Y
}
else if(i%2==1){
numY-=(numX-primaryNumX); //當爲半數分鐘的奇數倍時,由最初的生物X增值產生的生物X將進食同等數目的生物Y
}
if(i%6==0){
numX*=2; //三分鐘的整數倍,生物X增值一倍
}
if(i%4==0){
numY*=2; //兩分鐘的整數倍,生物Y增值一倍
}
}
System.out.println(numY);
}
public static void main(String[] args) {
calculate(10, 89, 60);
calculate(10, 90, 60);
// Scanner scanner=new Scanner(System.in);
// int numX=scanner.nextInt(),numY=scanner.nextInt();
// System.out.println(numX+" "+numY);
}
}
運行結果:
-979369984
94371840
94371840
23. 輸入信用卡號碼
/*
當你輸入信用卡號碼的時候,有沒有擔憂輸錯了而形成損失呢?其實能夠沒必要這麼擔憂,
由於並非一個隨便的信用卡號碼都是合法的,它必須經過Luhn算法來驗證經過。
該校驗的過程:
一、從卡號最後一位數字開始,逆向將奇數位(一、三、5等等)相加。
二、從卡號最後一位數字開始,逆向將偶數位數字,先乘以2(若是乘積爲兩位數,則將其減去9),再求和。
三、將奇數位總和加上偶數位總和,結果應該能夠被10整除。
例如,卡號是:5432123456788881
則奇數、偶數位(用紅色標出)分佈:5432123456788881
奇數位和=35
偶數位乘以2(有些要減去9)的結果:1 6 2 6 1 5 7 7,求和=35。
最後35+35=70 能夠被10整除,認定校驗經過。
請編寫一個程序,從鍵盤輸入卡號,而後判斷是否校驗經過。經過顯示:「成功」,不然顯示「失敗」。
好比,用戶輸入:356827027232780
程序輸出:成功
*/
package Question20_29;
import java.io.InputStreamReader;
import java.util.Scanner;
public class Question23 {
public static String judge(String s) {
int count=1;
int sum=0;
for (int i = s.length()-1; i >=0 ; i--,count++) {
if(count%2==1){
sum+=(s.charAt(i)-'0');
}else {
sum+=(s.charAt(i)-'0')*2>=10?(s.charAt(i)-'0')*2-9:(s.charAt(i)-'0')*2;
}
}
if(sum%10==0){
return "成功";
}else {
return "失敗";
}
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String s=scanner.nextLine();
System.out.println(judge(s));
}
}
運行結果:
輸入卡號:5432123456788881
成功
24. 輸入日期
/*
從鍵盤輸入一個日期,格式爲yyyy-M-d
要求計算該日期與1949年10月1日距離多少天
例如:
用戶輸入了:1949-10-2
程序輸出:1
用戶輸入了:1949-11-1
程序輸出:31
*/
package Question20_29;
import java.util.Scanner;
public class Question24MustRemember {
public static int dayOfYear[]={365,366};//平年365天,閏年366天
public static int dayOfMonth[][]={
{0,31,28,31,30,31,30,31,31,30,31,30,31},
{0,31,29,31,30,31,30,31,31,30,31,30,31}
};
public static int dayOfYearIndex(int year){ //根據是不是閏年來給出dayOfYear的數組的下標
if((year%4==0&&year%100!=0)||year%400==0){
return 1;
}
return 0;
}
public static int dayApartFromTheBrginOfYear(int year,int month,int day){//計算month月day日是year年的第幾天
int days=day;
for (int i = 1; i < month; i++) {
days+=dayOfMonth[dayOfYearIndex(year)][i];
}
return days;
}
public static int apartDays(String startDayString,String endDayString ) {
String s1[]=startDayString.split("-");
String s2[]=endDayString.split("-");
int days=0;
int flag;
int startYear=Integer.parseInt(s1[0]);
int endYear=Integer.parseInt(s2[0]);
int startMonth=Integer.parseInt(s1[1]);
int endMonth=Integer.parseInt(s2[1]);
int startDay=Integer.parseInt(s1[2]);
int endDay=Integer.parseInt(s2[2]);
for (int i = startYear; i < endYear; i++) {
days+=dayOfYear[dayOfYearIndex(i)];
}
days+=dayApartFromTheBrginOfYear(endYear,endMonth,endDay);
days-=dayApartFromTheBrginOfYear(startYear,startMonth,startDay);
return days;
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
String startDayString="1949-10-01";
String endDayString=scanner.nextLine();
System.out.println(apartDays(startDayString, endDayString));
}
}
運行結果:
輸入日期格式爲:(1949-10-2)
輸入第一個日期:1949-10-2
輸入第二個日期:1949-11-2
1949-10-2 到 1949-11-2
距離31天
25. 順時針螺旋填入
/*
從鍵盤輸入一個整數(1~20)
則以該數字爲矩陣的大小,把1,2,3…n*n 的數字按照順時針螺旋的形式填入其中。例如:
輸入數字2,則程序輸出:
1 2
4 3
輸入數字3,則程序輸出:
1 2 3
8 9 4
7 6 5
輸入數字4, 則程序輸出:
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
*/
package Question20_29;
import java.util.Scanner;
public class Question25 {
public static void print(int[][] array) {
for (int i = 0; i < array.length; i++) {
for (int j = 0; j < array.length; j++) {
System.out.printf("%4d",array[i][j]);
}
System.out.println();
}
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int n=scanner.nextInt();
int array[][]=new int[n][n];
int startIndex=0,endIndex=n-1,count=1,e=0;
while (e<=n/2) {
for (int i = startIndex; i <= endIndex; i++) {
array[e][i]=count++;
}
for (int i = startIndex+1; i <= endIndex; i++) {
array[i][n-1-e]=count++;
}
for (int i = endIndex-1; i>=startIndex; i--) {
array[n-1-e][i]=count++;
}
for (int i = endIndex-1; i>startIndex; i--) {
array[i][e]=count++;
}
startIndex++;
endIndex--;
e++;
}
print(array);
}
}
運行結果:
輸入一個整數:4
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
本身寫的,用到的控制變量比較多,因此程序讀起來容易混亂!
總體思路: (外圈實現:
1. 從(左->右)填充第一行
2.從(上->下)填充右側一列
3.從(右->左)填充最後一行
4.從(下->上)填充左側一列
只要最外圈能作出來,內圈同理,調整變量就能夠了)
方法二:
public class Demo08_two {
public static void show(int[][] m) {
for (int[] x : m) {
for (int y : x) {
System.out.print(y + "\t");
}
System.out.println("");
}
}
public static void helix(int n, int b, int[][] a) {
int i;
int j;
int k;
for (i = 0; i < n / 2; i++) {
for (j = i; j < n - i; j++)
/* 四個循環按不一樣的方向進行 */
a[i][j] = ++b;
for (k = i + 1, j--; k < n - i; k++)
a[k][j] = ++b;
for (j = --k, j--; j >= i; j--)
a[k][j] = ++b;
for (k--; k > i; k--)
a[k][i] = ++b;
}
if (n % 2 != 0) /* 若是是單數的話,要加上最大的那個數放在中間 */
a[i][i] = ++b;
}
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int i, j, k, n, b = 0;
System.out.print("輸入一個整數:");
n = scan.nextInt();
int[][] a = new int[n][n];
helix(n, b, a);
show(a);
}
}
運行結果:
輸入一個整數:4
1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
26. Playfair密碼
/*
* 一種Playfair密碼變種加密方法以下:首先選擇一個密鑰單詞(稱爲pair)(字母不重複,且都爲小寫字母),
* 而後與字母表中其餘字母一塊兒填入至一個5x5的方陣中,填入方法以下:
1.首先按行填入密鑰串。
2.緊接其後,按字母序按行填入不在密鑰串中的字母。
3.因爲方陣中只有25個位置,最後剩下的那個字母則不需變換。
若是密鑰爲youandme,則該方陣以下:
y o u a n
d m e b c
f g h i j
k l p q r
s t v w x
在加密一對字母時,如am,在方陣中找到以這兩個字母爲頂點的矩形(紅色字體):
y o u a n
d m e b c
f g h i j
k l p q r
s t v w x
這對字母的加密字母爲該矩形的另外一對頂點,如本例中爲ob。
請設計程序,使用上述方法對輸入串進行加密,並輸出加密後的串。
另外有以下規定:
一、一對一對取字母,若是最後只剩下一個字母,則不變換,直接放入加密串中;
二、若是一對字母中的兩個字母相同,則不變換,直接放入加密串中;
三、若是一對字母中有一個字母不在正方形中"如z",則不變換,直接放入加密串中;
四、若是字母對出如今方陣中的同一行或同一列,如df或hi,則只需簡單對調這兩個字母,即變換爲fd或ih;
五、若是在正方形中可以找到以字母對爲頂點的矩形,假如字母對爲am,則該矩形的另外一對頂點字母中,
與a同行的字母應在前面,在上例中應是ob;一樣若待變換的字母對爲ta,則變換後的字母對應爲wo;
六、本程序中輸入串均爲小寫字母,並不含標點、空格或其它字符。
解密方法與加密相同,即對加密後的字符串再加密,將獲得原始串。
要求輸入形式以下:
從控制檯輸入兩行字符串,第一行爲密鑰單詞(長度小於等於25),第二行爲待加密字符串(長度小於等於50),
兩行字符串末尾都有一個回車換行符,而且兩行字符串均爲小寫字母,不含其它字符。
在標準輸出上輸出加密後的字符串。
例如,若輸入:
youandme
welcometohangzhou
則表示輸入的密鑰單詞爲youandme,造成的正方形如上所示;待加密字符串爲welcometohangzhou。
在正方形中能夠找到以第一對字母we爲頂點的矩形,對應另外一對頂點字母爲vb,所以加密後爲vb,
同理可找到與字母對lc,et,oh,ho對應的頂點字母對。而字母對om位於上述正方形中的同一列,
因此直接以顛倒這兩個字母來加密,即爲mo,字母對an同理。字母對gz中的z不在上述正方形中,
所以原樣放到加密串中。最後剩一個字母u也原樣輸出。
所以輸出的結果爲:
vbrmmomvugnagzguu
vbrmmomvugnagzguu
vbrmmomvugnagzguu
要求考生把全部類寫在一個文件中。調試好後,存入與考生文件夾下對應題號的「解答.txt」中便可。
相關的工程文件不要拷入。請不要使用package語句。
另外,源程序中只能出現JDK1.5中容許的語法或調用。不能使用1.6或更高版本。
*/
package Question20_29;
import java.util.Scanner;
import java.util.Vector;
public class Question26 {
public static char initArray(char[][] array, String pair) {
Vector<Character>vector=new Vector<Character>();
for (char i = 'a'; i <='z'; i++) {
vector.add(i);
}
for (int i = 0; i < pair.length(); i++) {
vector.remove((Character)pair.charAt(i));
array[i/5][i%5]=pair.charAt(i);
}
for (int i = 0,j=pair.length() ; i < vector.size()-1; i++,j++) {
array[j/5][j%5]=vector.elementAt(i);
}
return vector.elementAt(vector.size()-1);
}
public static String passwordAfterChange(char[][] array,String password,char unUsedch) {
StringBuffer sb=new StringBuffer();
for (int i = 0; i < password.length(); i+=2) {
if(i+1<password.length()){
if(password.charAt(i)==unUsedch||password.charAt(i+1)==unUsedch){//若是一對字母中有一個字母不在正方形中"如z",則不變換,直接放入加密串中
sb.append(password.charAt(i));
sb.append(password.charAt(i+1));
}else if (password.charAt(i)==password.charAt(i+1)) {//若是一對字母中的兩個字母相同,則不變換,直接放入加密串中
sb.append(password.charAt(i));
sb.append(password.charAt(i+1));
}else {
int ch1i=0,ch1j=0,ch2i=0,ch2j = 0;
for (int j = 0; j < array.length; j++) {
for (int j2 = 0; j2 < array.length; j2++) {
if(array[j][j2]==password.charAt(i)){
ch1i=j;ch1j=j2;
}else if(array[j][j2]==password.charAt(i+1)){
ch2i=j;ch2j=j2;
}
}
}
if(ch1i==ch2i||ch1j==ch2j){//若是字母對出如今方陣中的同一行或同一列,如df或hi,則只需簡單對調這兩個字母,即變換爲fd或ih
sb.append(password.charAt(i+1));
sb.append(password.charAt(i));
}else {
sb.append(array[ch1i][ch2j]);
sb.append(array[ch2i][ch1j]);
}
}
}else {//一對一對取字母,若是最後只剩下一個字母,則不變換,直接放入加密串中
sb.append(password.charAt(i));
}
}
return sb.toString();
}
public static void main(String[] args) {
char array[][]=new char[5][5];
Scanner scanner = new Scanner(System.in);
String pair = scanner.nextLine();
String password=scanner.nextLine();
char unUsedch=initArray(array, pair);
System.out.println(passwordAfterChange(array, password, unUsedch));
}
}
運行結果:
輸入密鑰單詞:youandme
輸入待加密字符:welcometohangzhou
y o u a n
d m e b c
f g h i j
k l p q r
s t v w x
加密結果:vbrmommvugnagzguu
解密結果:welcometohangzhou
27. 金額組合
/*
某財務部門結帳時發現總金額不對頭。極可能是從明細上漏掉了某1筆或幾筆。
若是已知明細帳目清單,能經過編程找到漏掉的是哪1筆或幾筆嗎?
若是有多種可能,則輸出全部可能的狀況。
咱們規定:用戶輸入的第一行是:有錯的總金額。
接下來是一個整數n,表示下面將要輸入的明細帳目的條數。
再接下來是n行整數,分別表示每筆帳目的金額。
要求程序輸出:全部可能漏掉的金額組合。每一個狀況1行。金額按照從小到大排列,中間用空格分開。
好比:
用戶輸入:
6
5
3
2
4
3
1
代表:有錯的總金額是6;明細共有5筆。
此時,程序應該輸出:
1 3 3
1 2 4
3 4
爲了方便,不妨假設全部的金額都是整數;每筆金額不超過1000,金額的明細條數不超過100。
*/
package Question20_29;
import java.util.Arrays;
import java.util.Scanner;
import java.util.Vector;
import java.util.concurrent.PriorityBlockingQueue;
import javax.swing.text.AbstractDocument.BranchElement;
public class Question27 {
public static String elementOfPriorityBlockingQueue(int array[],boolean used[]) {
PriorityBlockingQueue<Integer>priorityBlockingQueue=new PriorityBlockingQueue<Integer>();
for (int i = 0; i < used.length; i++) {
if(used[i]==true){
priorityBlockingQueue.add(array[i]);
}
}
StringBuffer sb=new StringBuffer();
while (!priorityBlockingQueue.isEmpty()) {
sb.append(priorityBlockingQueue.poll());
}
return sb.toString();
}
public static void exeForward(PriorityBlockingQueue<String>priorityBlockingQueue,int array[],boolean used[],int index,int sum,int tSum) {
if(sum>tSum){
return;
}
if(sum==tSum){
String string=elementOfPriorityBlockingQueue(array, used);
if(!priorityBlockingQueue.contains(string)){
priorityBlockingQueue.add(string);
}
return;
}
if(index<=array.length-1){
for (int i = 0; i <=1; i++) {
used[index]=(i==0?false:true);
sum+=array[index]*i;
exeForward(priorityBlockingQueue,array, used, index+1, sum, tSum);
sum-=array[index]*i;
used[index]=(i==1?false:true);
}
}else {
return;
}
}
public static void main(String[] args) {
int tSum;
int n;
Vector<Integer>vector=new Vector<Integer>();
Scanner scanner=new Scanner(System.in);
PriorityBlockingQueue<String>priorityBlockingQueue=new PriorityBlockingQueue<String>();
tSum=scanner.nextInt();
n=scanner.nextInt();
int array[]=new int[n];
boolean used[]=new boolean[n];
tSum*=(-1);
for (int i = 0; i < n; i++) {
array[i]=scanner.nextInt();
tSum+=array[i];
}
exeForward(priorityBlockingQueue,array, used, 0, 0, tSum);
while (!priorityBlockingQueue.isEmpty()) {
String string=priorityBlockingQueue.poll();
for (int i = 0; i < string.length(); i++) {
System.out.print(string.charAt(i));
if(i!=string.length()-1){
System.out.print(" ");
}
}
System.out.println();
}
}
}
運行結果:
6
5
3
2
4
3
1
輸出結果:
3 4
1 3 3
1 2 4
28. 拼出漂亮的表格
/*
* 在中文Windows環境下,控制檯窗口中也能夠用特殊符號拼出漂亮的表格來。
好比:
┌─┬─┐
│ │ │
├─┼─┤
│ │ │
└─┴─┘
其實,它是由以下的符號拼接的:
左上 = ┌
上 = ┬
右上 = ┐
左 = ├
中心 = ┼
右 = ┤
左下= └
下 = ┴
右下 = ┘
垂直 = │
水平 = ─
本題目要求編寫一個程序,根據用戶輸入的行、列數畫出相應的表格來。
例如用戶輸入:
3 2
則程序輸出:
┌─┬─┐
│ │ │
├─┼─┤
│ │ │
├─┼─┤
│ │ │
└─┴─┘
用戶輸入:
2 3
則程序輸出:
┌─┬─┬─┐
│ │ │ │
├─┼─┼─┤
│ │ │ │
└─┴─┴─┘
要求考生把全部類寫在一個文件中。調試好後,存入與考生文件夾下對應題號的「解答.txt」中便可。相關的工程文件不要拷入。請不要使用package語句。
另外,源程序中只能出現JDK1.5中容許的語法或調用。不能使用1.6或更高版本。
*/
package Question20_29;
import java.util.Scanner;
public class Question28 {
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
int hang=scanner.nextInt(),lie=scanner.nextInt();
for (int i = 0; i < hang; i++) {
if(i==0){
System.out.print("┌─");
for (int j = 0; j < lie-1; j++) {
System.out.print("┬─");
}
System.out.println("┐");
for (int j = 0; j < lie; j++) {
System.out.print("│ ");
}
System.out.println("│");
}else {
System.out.print("├─");
for (int j = 0; j < lie-1; j++) {
System.out.print("┼─");
}
System.out.println("┤");
for (int j = 0; j < lie; j++) {
System.out.print("│ ");
}
System.out.println("│");
}
}
System.out.print("└─");
for (int j = 0; j < lie-1; j++) {
System.out.print("┴─");
}
System.out.println("┘");
//System.out.print("┌");System.out.print("─");System.out.print("┬");System.out.print("─");System.out.print("┐");
}
}
運行結果:
請輸出兩個數,行和列 ,例: 3 4
3 4
┌─┬─┬─┬─┐
│ │ │ │ │
├─┼─┼─┼─┤
│ │ │ │ │
├─┼─┼─┼─┤
│ │ │ │ │
└─┴─┴─┴─┘
29. 迷宮問題
/*
迷宮問題
對於走迷宮,人們提出過不少計算機上的解法。深度優先搜索、廣度優先搜索是使用最廣的方法。生活中,人們更願意使用「緊貼牆壁,靠右行走」的簡單規則。
下面的代碼則採用了另外一種不一樣的解法。它把走迷宮的過程比作「染色過程」。
假設入口點被染爲紅色,它的顏色會「傳染」給與它相鄰的可走的單元。
這個過程不斷進行下去,若是最終出口點被染色,則迷宮有解。
仔細分析代碼中的邏輯,填充缺乏的部分。把填空的答案(僅填空處的答案,不包括題面)存入考生文件夾下對應題號的「解答.txt」中便可。
*/
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
class Cell{ // 單元格
int row; // 哪行
int col; // 哪列
Cell from; // 開始點
public Cell(int row,int col,Cell from){
this.row = row;
this.col = col;
this.from = from;
}
}
public class T04 {
static char[][] maze = {
{'#','#','#','#','B','#','#','#','#','#','#','#'},
{'#','#','#','#','.','.','.','.','#','#','#','#'},
{'#','#','#','#','.','#','#','#','#','.','.','#'},
{'#','.','.','.','.','#','#','#','#','#','.','#'},
{'#','.','#','#','#','#','#','.','#','#','.','#'},
{'#','.','#','#','#','#','#','.','#','#','.','#'},
{'#','.','#','#','.','.','.','.','.','.','.','#'},
{'#','.','#','#','.','#','#','#','.','#','.','#'},
{'#','.','.','.','.','#','#','#','.','#','.','#'},
{'#','#','.','#','.','#','#','#','.','#','.','A'},
{'#','#','.','#','#','#','.','.','.','#','#','#'},
{'#','#','#','#','#','#','#','#','#','#','#','#'}
};
// 顯示迷宮
public static void show(){
for(int i=0;i<maze.length;i++){
for(int j=0;j<maze[i].length;j++){
System.out.print(" "+maze[i][j]);
}
System.out.println();
}
}
// 染色
public static Cell colorCell(Set<Cell> from,Set<Cell> desc){
Iterator<Cell> iter = from.iterator();
while(iter.hasNext()){
Cell a = iter.next();
Cell c[] = new Cell[4];
c[0] = new Cell(a.row-1,a.col,a); // 向上走
c[1] = new Cell(a.row+1,a.col,a); // 向下走
c[2] = new Cell(a.row,a.col-1,a); // 向左走
c[3] = new Cell(a.row,a.col+1,a); // 向右走
for(int i=0;i<4;i++){
if(c[i].row<0 || c[i].row>=maze.length) continue;
if(c[i].col<0 || c[i].col>=maze[0].length) continue;
char x = maze[c[i].row][c[i].col]; // 取得單元格對應字符
if(x=='B') return a;
if(x=='.'){
maze[c[i].row][c[i].col] = '?'; // 染色
desc.add(c[i]);
}
}
}
return null;
}
//
public static void resolve(){
Set<Cell> set = new HashSet<Cell>();
set.add(new Cell(9,11,null));
for(;;){
Set<Cell> set1 = new HashSet<Cell>();
// 出口 a.from.from.from.....<-(set.get(0).from)==null<-入口
Cell a = colorCell(set,set1);
if(a!=null){ // 找到解
System.out.println("找到解!");
while(a!=null){ // 當前a裏包含a.from 一直往前推
maze[a.row][a.col] = '+'; // 染色路徑
a = a.from;
}
break;
}
if(set1.isEmpty()){ // 遍歷因此一直到沒有路走,這時 set1爲空
System.out.println("無解!");
break;
}
set = set1; // 向裏邊
}
}
public static void main(String[] args){
show();
resolve();
show();
}
}
運行結果:
# # # # B # # # # # # #
# # # # . . . . # # # #
# # # # . # # # # . . #
# . . . . # # # # # . #
# . # # # # # . # # . #
# . # # # # # . # # . #
# . # # . . . . . . . #
# . # # . # # # . # . #
# . . . . # # # . # . #
# # . # . # # # . # . A
# # . # # # . . . # # #
# # # # # # # # # # # #
找到解!
# # # # B # # # # # # #
# # # # + . . . # # # #
# # # # + # # # # ? ? #
# + + + + # # # # # ? #
# + # # # # # ? # # ? #
# + # # # # # ? # # ? #
# + # # + + + + + + + #
# + # # + # # # ? # + #
# + + + + # # # ? # + #
# # ? # ? # # # ? # + +
# # ? # # # ? ? ? # # #
# # # # # # # # # # # #
30. 數字黑洞
/*
任意一個5位數,好比:34256,把它的各位數字打亂,從新排列,能夠獲得
一個最大的數:65432,一個最小的數23456。
求這兩個數字的差,得:41976,把這個數字再次重複上述過程(若是不足5位,則前邊補0)。如此往復,數字會落入某個循環圈(稱爲數字黑洞)。
好比,剛纔的數字會落入:[82962,75933, 63954, 61974]這個循環圈。
請編寫程序,找到5位數全部可能的循環圈,並輸出,每一個循環圈佔1行。
其中5位數全都相同則循環圈爲[0],這個能夠不考慮。循環圈的輸出格式仿照:
[82962,75933, 63954, 61974]其中數字的前後順序能夠不考慮。
*/
package Question30_39;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Scanner;
import java.util.Set;
public class Question30TooDifficultMustRemember{
public static int MaxSubMin(int n) {
StringBuffer sb=new StringBuffer(""+n);
while (sb.length()<5) {
sb.insert(0, '0');
}
char ch[]=(sb.toString()).toCharArray();
Arrays.sort(ch);
int max=(ch[4]-'0')*10000+(ch[3]-'0')*1000+(ch[2]-'0')*100+(ch[1]-'0')*10+ch[0]-'0';
int min=(ch[0]-'0')*10000+(ch[1]-'0')*1000+(ch[2]-'0')*100+(ch[3]-'0')*10+ch[4]-'0';
return max-min;
}
public static Set<Integer> blackHole(int n) {
Set<Integer> set=new LinkedHashSet<Integer>();
set.add(n);
while(true){
n=MaxSubMin(n);
if(set.add(n)==false){
Set<Integer>tSet=new LinkedHashSet<Integer>();
for (Iterator iterator = set.iterator(); iterator.hasNext();) {
Integer integer = (Integer) iterator.next();
if(integer==n){
break;
}else {
tSet.add(integer);
}
}
set.removeAll(tSet);
break;
}
}
return set;
}
public static void main(String[] args) {
Scanner scanner=new Scanner(System.in);
// int n=scanner.nextInt();
Set<Set<Integer>>set=new LinkedHashSet<>();
for (int i = 10000; i < 100000; i++) {
set.add(blackHole(i));
}
for (Iterator iterator = set.iterator(); iterator.hasNext();) {
Set<Integer> set2 = (Set<Integer>) iterator.next();
System.out.println(set2);
}
}
}
運行結果:
[0]
[74943, 62964, 71973, 83952]
[63954, 61974, 82962, 75933]
[53955, 59994]
31. 基因牛
/*
張教授採用基因干預技術成功培養出一頭母牛,三年後,這頭母牛每一年會生出1頭母牛,
生出來的母牛三年後,又能夠每一年生出一頭母牛。如此循環下去,請問張教授n年後有多少頭母牛?
如下程序模擬了這個過程,請填寫缺失的代碼。
*/
import java.util.ArrayList;
import java.util.List;
class Cow{
private int age;
public Cow afterYear(){
age++;
return age > 2 ? new Cow() : null; // 填空
}
public static void showTotalCowNum(int n){
List<Cow> list = new ArrayList<Cow>();
list.add(new Cow());
for (int i = 0; i < n; i++) {
int cowCount = list.size();
for (int j = 0; j < cowCount; j++){
Cow cow = list.get(j).afterYear();
if (cow != null){
cow.afterYear(); // 填空
list.add(cow);
}
}
}
System.out.println(n + "年後,共有:" + list.size());
}
}
class Demo05{
public static void main(String[] args){
Cow.showTotalCowNum(13);
}
}
運行結果:
13年後,共有:233
32. 最近距離
/*
已知平面上的若干點的位置,存入一個List中。如今須要計算全部這些點中,
距離最近的兩個點間的最小距離。請補全缺失的代碼。
把填空的答案(僅填空處的答案,不包括題面)存入考生文件夾下對應題號的「解答.txt」中便可。
*/
import java.util.ArrayList;
import java.util.List;
class MyPoint{
private double x; // 橫座標
private double y; // 縱座標
public MyPoint(double x, double y){
this.x = x;
this.y = y;
}
public static double distance(MyPoint p1, MyPoint p2){
double dx = p1.x - p2.x;
double dy = p1.y - p2.y;
return Math.sqrt(dx*dx + dy*dy);
}
/*
lst中含有若干個點的座標
返回其中距離最小的點的距離
*/
public static double getMinDistance(List<MyPoint> lst){
if(lst==null || lst.size()<2) return Double.MAX_VALUE;
double r = Double.MAX_VALUE;
MyPoint p0 = lst.remove(0);
for(int i=0; i<lst.size(); i++){
MyPoint p = lst.get(i);
double d = MyPoint.distance(p0,p);
if(d<r) r = d; // 填空
}
double d2 = getMinDistance(lst);
return d2 < r ? d2 : r;
}
}
class Demo04{
public static void main(String[] args){
List<MyPoint> list = new ArrayList<MyPoint>() ;
list.add(new MyPoint(31,4));
list.add(new MyPoint(1,2));
list.add(new MyPoint(1,1));
list.add(new MyPoint(1,4));
System.out.println(MyPoint.getMinDistance(list));
}
}
運行結果:
1.0
33. 字符串反轉
/*
咱們把「cba」稱爲「abc」的反轉串。
求一個串的反轉串的方法不少。下面就是其中的一種方法,代碼十分簡潔(甚至有些神祕),
請聰明的你經過給出的一點點線索補充缺乏的代碼。
把填空的答案(僅填空處的答案,不包括題面)存入考生文件夾下對應題號的「解答.txt」中便可。
*/
public class Demo03 {
public static String reverseString(String s){
if(s.length()<2||s==null) return s;
return reverseString(s.substring(1))+s.charAt(0);
}
public static void main(String[] args){
String s = "123456";
String ss = reverseString(s);
System.out.println(ss);
}
}
運行結果:
654321
34. 孿生素數
/*
所謂孿生素數指的就是間隔爲 2 的相鄰素數,它們之間的距離已經近得不能再近了,
就象孿生兄弟同樣。最小的孿生素數是 (3, 5),
在 100 之內的孿生素數還有 (5, 7), (11, 13), (17, 19), (29, 31),
(41, 43), (59, 61) 和 (71, 73),總計有 8 組。
可是隨着數字的增大,孿生素數的分佈變得愈來愈稀疏,尋找孿生素數也變得愈來愈困難。
那麼會不會在超過某個界限以後就不再存在孿生素數了呢?
孿生素數有無窮多對!這個猜測被稱爲孿生素數猜測,至今沒有被嚴格證實。
但藉助於計算機咱們確實能夠找到任意大數範圍內的全部孿生素數對。
下面的代碼求出了正整數n之內(不含n)的全部孿生素數對的個數。
好比,當n=100的時候,該方法返回8。試補全缺乏的代碼。
把填空的答案(僅填空處的答案,不包括題面)存入考生文件夾下對應題號的「解答.txt」中便可。
*/
class Demo02{
// 判斷是不是素數
public static boolean isPrime(int x){
for(int i=2; i<=x/2; i++){
if(x%i==0) return false;
}
return true;
}
// 是不是孿生素數
public static int twinPrimeNum(int n){
int sum = 0;
for(int i=2; i<n; i++){
if(isPrime(i) && isPrime(i+2) && (i+2)<=n) sum++;
}
return sum; // 返回個數
}
public static void main(String[] args){
int n = 1000;
System.out.println(twinPrimeNum(n));
}
}
35. 圓周率
/*
我國古代數學家對圓周率方面的研究工做,成績是突出的。三國時期的劉徽、南北朝時期的祖沖之都在這個領域取得過輝煌戰績。
有了計算機,圓周率的計算變得十分容易了。現在,人們創造了上百種方法求π的值。其中比較經常使用且易於編程的是無窮級數法。
π/4 = 1 – 1/3 + 1/5 – 1/7 + 1/9 - …
是初學者特別喜歡的一個級數形式,但其缺點是收斂太慢。
π/2 = 1 + 1/3 +1/3*2/5 + 1/3*2/5*3/7 + 1/3*2/5*3/7*4/9 + …
是收斂很快的一個級數方法。下面的代碼演示了用這種方法計算π值。請填寫缺失的代碼部分。
把填空的答案(僅填空處的答案,不包括題面)存入考生文件夾下對應題號的「解答.txt」中便可。
*/
public class Demo01 {
public static void main(String[] args){
double x = 1;
double y = 1;
int a = 1;
int b = 3;
while(y>1e-15){
y = y*a/b;<span style="white-space:pre"> </span>// 填空
x += y;
a++;
b += 2;
}
System.out.println(x*2);
}
}
36. 泊松分酒
/*
泊松是法國數學家、物理學家和力學家。他一輩子致力科學事業,成果頗多。
有許多著名的公式定理以他的名字命名,好比機率論中著名的泊松分佈。
有一次閒暇時,他提出過一個有趣的問題,後稱爲:「泊松分酒」。
在我國古代也提出過相似問題,遺憾的是沒有進行完全探索,其中流傳較可能是:「韓信走馬分油」問題。
有3個容器,容量分別爲12升,8升,5升。其中12升中裝滿油,另外兩個空着。
要求你只用3個容器操做,最後使得某個容器中正好有6升油。
下面的列表是可能的操做狀態記錄:
12,0,0
4,8,0
4,3,5
9,3,0
9,0,3
1,8,3
1,6,5
每行3個數據,分別表示12,8,6升容器中的油量
第一行表示初始狀態,第二行表示把12升倒入8升容器後的狀態,第三行是8升倒入5升,...
固然,同一個題目可能有多種不一樣的正確操做步驟。
本題目的要求是,請你編寫程序,由用戶輸入:各個容器的容量,開始的狀態,
和要求的目標油量,程序則經過計算輸出一種實現的步驟(不須要找到全部可能的方法)。
若是沒有可能實現,則輸出:「不可能」。
例如,用戶輸入:
12,8,5,12,0,0,6
用戶輸入的前三個數是容器容量(由大到小),接下來三個數是三個容器開始時的油量配置,
最後一個數是要求獲得的油量(放在哪一個容器裏獲得均可以)
則程序能夠輸出(答案不惟一,只驗證操做可行性):
12,0,0
4,8,0
4,3,5
9,3,0
9,0,3
1,8,3
1,6,5
每一行表示一個操做過程當中的油量狀態。
注意:
請仔細調試!您的程序只有能運行出正確結果的時候纔有機會得分!
請把全部類寫在同一個文件中,調試好後,存入與【考生文件夾】下對應題號的「解答.txt」中便可。
相關的工程文件不要拷入。
請不要使用package語句。
源程序中只能出現JDK1.5中容許的語法或調用。不能使用1.6或更高版本。
*/
package Question30_39;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Scanner;
import java.util.Set;
import java.util.Vector;
public class Question36TooDifficultMustRemember {
public static List<Integer> distribute(List<Integer> capacityList,List<Integer> oilSizeList,int where,int to) {
List<Integer>tList =new ArrayList<Integer>();
tList.addAll(oilSizeList);
if(oilSizeList.get(where)==0){
return null;
}else if (oilSizeList.get(where)>=capacityList.get(to)-oilSizeList.get(to)) {
tList.set(to, capacityList.get(to));
tList.set(where, oilSizeList.get(where)-(capacityList.get(to)-oilSizeList.get(to)));
return tList;
}else if(oilSizeList.get(where)<=capacityList.get(to)-oilSizeList.get(to)){
tList.set(to, oilSizeList.get(to)+oilSizeList.get(where));
tList.set(where, 0);
return tList;
}
return null;
}
public static boolean exeForward(Set<List<Integer>>set,List<Integer> capacityList,List<Integer> oilSizeList,int NeedOilSize) {
// for (List<Integer> list : set) {
// System.out.print(list+" ");
// }
// System.out.println();
for (Integer integer : oilSizeList) {
if(integer==NeedOilSize){
for (List<Integer> list : set) {
// System.out.print(list+" ");
// System.out.print(list.size()+" ");
for (Iterator iterator = list.iterator(); iterator
.hasNext();) {
Integer integer2 = (Integer) iterator.next();
System.out.print(integer2);
if(iterator.hasNext()){
System.out.print(",");
}else {
System.out.print("\n");
}
}
}
return true;
}
}
Vector<List<Integer>>vector=new Vector<List<Integer>>();
vector.add(distribute(capacityList, oilSizeList, 0, 1));
vector.add(distribute(capacityList, oilSizeList, 0, 2));
vector.add(distribute(capacityList, oilSizeList, 1, 0));
vector.add(distribute(capacityList, oilSizeList, 1, 2));
vector.add(distribute(capacityList, oilSizeList, 2, 0));
vector.add(distribute(capacityList, oilSizeList, 2, 1));
for (int i = 0; i < vector.size(); i++) {
if(vector.get(i)!=null){
if(set.add(vector.get(i))){
if(exeForward(set, capacityList, vector.get(i), NeedOilSize)==true){
return true;
}
set.remove(vector.get(i));
}
}
}
return false;
}
public static void main(String[] args){
Scanner scanner=new Scanner(System.in);
Set<List<Integer>>set=new LinkedHashSet<List<Integer>>();
List<Integer>tList=new ArrayList<Integer>();
for (int i = 0; i < 3; i++) {
tList.add(0);
}
List<Integer> capacityList=new ArrayList<>(tList);
List<Integer> oilSizeList=new ArrayList<>(tList);
int NeedOilSize;
String ts=scanner.nextLine();
String tss[]=ts.split("\\,");
for (int i = 0; i < capacityList.size(); i++) {
capacityList.set(i, Integer.parseInt(tss[i]));
}
int totalOil=0;
for (int i = 0; i < capacityList.size(); i++) {
oilSizeList.set(i, Integer.parseInt(tss[i+3]));
totalOil+=Integer.parseInt(tss[i+3]);
}
NeedOilSize=Integer.parseInt(tss[6]);
if(NeedOilSize>totalOil){
System.out.println("不可能");
return;
}
boolean posible=false;
for (int i = 0; i < capacityList.size(); i++) {
if(capacityList.get(i)>NeedOilSize){
posible=true;
break;
}
}
if(posible==false){
System.out.println("不可能");
return;
}
exeForward(set, capacityList, oilSizeList, NeedOilSize);
}
}
運行結果:
輸入數據(格式爲7個數字用","號隔開,例:)12,8,5,12,0,0,6
12,8,5,12,0,0,6
12 0 0
4 8 0
4 3 5
9 3 0
9 0 3
1 8 3
1 6 5
記錄數:(7)
37. 矩形的關係。
/*
在編寫圖形界面軟件的時候,常常會遇處處理兩個矩形的關係。
如圖【1.jpg】所示,矩形的交集指的是:兩個矩形重疊區的矩形,固然也可能不存在(參看【2.jpg】)。
兩個矩形的並集指的是:能包含這兩個矩形的最小矩形,它必定是存在的。
本題目的要求就是:由用戶輸入兩個矩形的座標,程序輸出它們的交集和並集矩形。
矩形座標的輸入格式是輸入兩個對角點座標,注意,不保證是哪一個對角,
也不保證順序(你能夠體會一下,在桌面上拖動鼠標拉矩形,4個方向均可以的)。
輸入數據格式:
x1,y1,x2,y2
x1,y1,x2,y2
數據共兩行,每行表示一個矩形。每行是兩個點的座標。x座標在左,y座標在右。
座標系統是:屏幕左上角爲(0,0),x座標水平向右增大;y座標垂直向下增大。
要求程序輸出格式:
x1,y1,長度,高度
x1,y1,長度,高度
也是兩行數據,分別表示交集和並集。若是交集不存在,則輸出「不存在」
前邊兩項是左上角的座標。後邊是矩形的長度和高度。
例如,用戶輸入:
100,220,300,100
150,150,300,300
則程序輸出:
150,150,150,70
100,100,200,200
例如,用戶輸入:
10,10,20,20
30,30,40,40
則程序輸出:
不存在
10,10,30,30
*/
import java.awt.Rectangle;
import java.util.Scanner;
public class Demo13_Rectang {
public static Rectangle getRec(Rectangle[] rec){
Scanner scan = new Scanner(System.in);
String s = scan.nextLine();
String[] ss = s.split(",");
int x1 = Integer.parseInt(ss[0]);
int y1 = Integer.parseInt(ss[1]);
int x2 = Integer.parseInt(ss[2]);
int y2 = Integer.parseInt(ss[3]);
// 若是(x1,y1)(x2,y2)分別在(左上,右下,右上,左下)時
return new Rectangle(Math.min(x1, x2),Math.min(y1, y2),
Math.abs(x2-x1),Math.abs(y2-y1));
}
public static void op(Rectangle[] rec){
Rectangle r,rr;
if(rec[0].intersects(rec[1])){
r = rec[0].intersection(rec[1]); // 交集
System.out.println(r.x+","+r.y+","+r.width+","+r.height);
}else{
System.out.println("不存在");
}
rr = rec[0].union(rec[1]); // 並集
System.out.println(rr.x+","+rr.y+","+rr.width+","+rr.height);
}
public static void main(String[] args){
Rectangle rec[] = new Rectangle[2];
rec[0] = getRec(rec); // 第一個矩形
rec[1] = getRec(rec); // 第二個矩形
op(rec); // 輸出 交集 和 並集
}
}
運行結果1:
100,220,300,100
150,150,300,300
150,150,150,70
100,100,200,200
運行結果2:
10,10,20,20
30,30,40,40
不存在
10,10,30,30
38. 測量到的工程數據
/*
[12,127,85,66,27,34,15,344,156,344,29,47,....]
這是某設備測量到的工程數據。
因工程要求,須要找出最大的5個值。
通常的想法是對它排序,輸出前5個。但當數據較多時,這樣作很浪費時間。
由於對輸出數據之外的數據進行排序並不是工程要求,即使是要輸出的5個數字,
也並不要求按大小順序,只要找到5個就能夠。
如下的代碼採用了另外的思路。考慮若是手裏已經抓着5個最大數,再來一個數據怎麼辦呢?
讓它和手裏的數據比,若是比哪一個大,就搶佔它的座位,讓那個被擠出來的再本身找位子,....
請分析代碼邏輯,並推測劃線處的代碼。
答案寫在 「解答.txt」 文件中
注意:只寫劃線處應該填的內容,劃線先後的內容不要抄寫。
*/
import java.util.*;
public class Demo11_B23 {
public static List<Integer> max5(List<Integer> lst) {
if (lst.size() <= 5)
return lst;
int a = lst.remove(lst.size() - 1); // 填空
List<Integer> b = max5(lst);
for (int i = 0; i < b.size(); i++) {
int t = b.get(i);
if (a > t) {
lst.set(i, a); // 填空
a = t;
}
}
return b;
}
public static void main(String[] args) {
List<Integer> lst = new Vector<Integer>();
lst.addAll(Arrays.asList(12, 127, 85, 66, 27, 34, 15, 344, 156, 344,
29, 47));
System.out.println(max5(lst));
}
}
運行結果:
[344, 344, 156, 127, 85]
39. 南北朝時
/*
* 南北朝時,我國數學家祖沖之首先把圓周率值計算到小數點後六位,比歐洲早了1100年!
* 他採用的是稱爲「割圓法」的算法,實際上已經蘊含着現代微積分的思想。
如圖【1.jpg】所示,圓的內接正六邊形周長與圓的周長近似。
多邊形的邊越多,接近的越好!咱們從正六邊形開始割圓吧。
如圖【2.jpg】所示,從圓心作弦的垂線,可把6邊形分割爲12邊形。
該12邊形的邊長a'的計算方法很容易利用勾股定理給出。
以後,再分割爲正24邊形,....如此循環會愈來愈接近圓周。
之因此從正六邊開始,是由於此時邊長與半徑相等,便於計算。取半徑值爲1,開始割圓吧!
如下代碼描述了割圓過程。
程序先輸出了標準圓周率值,緊接着輸出了不斷分割過程當中多邊形邊數和所對應的圓周率逼近值。
*/
public class Demo10_B21
{
public static void main(String[] args)
{
System.out.println("標準 " + Math.PI);
double a = 1;
int n = 6;
for(int i=0; i<10; i++)
{
double b = Math.sqrt(1-(a/2)*(a/2));
a = Math.sqrt((1-b)*(1-b) + (a/2)*(a/2));
n = n*2; //填空
System.out.println(n + " " + n*a/2 ); // 填空
}
}
}
運行結果:
標準 3.141592653589793
12 3.105828541230249
24 3.1326286132812378
48 3.1393502030468667
96 3.14103195089051
192 3.1414524722854624
384 3.141557607911858
768 3.1415838921483186
1536 3.1415904632280505
3072 3.1415921059992717
6144 3.1415925166921577
40. 數字的值返回
/*
如下的靜態方法實現了:把串s中第一個出現的數字的值返回。
若是找不到數字,返回-1
例如:
s = "abc24us43" 則返回2
s = "82445adb5" 則返回8
s = "ab" 則返回-1
*/
public class Demo09_FirstNum {
public static int getFirstNum(String s)
{
if(s==null || s.length()==0) return -1;
char c = s.charAt(0);
if(c>='0' && c<='9') return c-'0'; //填空
return getFirstNum(s.substring(1)); //填空
}
public static void main(String[] args){
String s = "abc24us43";
System.out.println(getFirstNum(s));
}
}
運行結果:
2