1. 程式人生 > >第八屆藍橋杯大賽個人賽決賽(軟體類)真題 Java大學B組 答案

第八屆藍橋杯大賽個人賽決賽(軟體類)真題 Java大學B組 答案



標題:平方十位數


由0~9這10個數字不重複、不遺漏,可以組成很多10位數字。
這其中也有很多恰好是平方數(是某個數的平方)。


比如:1026753849,就是其中最小的一個平方數。


請你找出其中最大的一個平方數是多少?


注意:你需要提交的是一個10位數字,不要填寫任何多餘內容。


答案:9814072356


public class Main {
public static void main(String[] args) {
boolean b = true;
long n=99999;
while(b){
long n2=n*n;
String s = n2+"";
char c[]=s.toCharArray();
boolean bool = false;
for(int i=0;i<9;i++){
for(int j=i+1;j<10;j++)
{
if(c[i]==c[j]){
bool=true;
break;
}
}
if(bool)break;
}
if(bool){
n--;
continue;
}
else{
b=false;
System.out.println(n2);
}
}
}

}



標題:生命遊戲


康威生命遊戲是英國數學家約翰·何頓·康威在1970年發明的細胞自動機。  
這個遊戲在一個無限大的2D網格上進行。


初始時,每個小方格中居住著一個活著或死了的細胞。
下一時刻每個細胞的狀態都由它周圍八個格子的細胞狀態決定。


具體來說:


1. 當前細胞為存活狀態時,當週圍低於2個(不包含2個)存活細胞時, 該細胞變成死亡狀態。(模擬生命數量稀少)
2. 當前細胞為存活狀態時,當週圍有2個或3個存活細胞時, 該細胞保持原樣。
3. 當前細胞為存活狀態時,當週圍有3個以上的存活細胞時,該細胞變成死亡狀態。(模擬生命數量過多)
4. 當前細胞為死亡狀態時,當週圍有3個存活細胞時,該細胞變成存活狀態。 (模擬繁殖)


當前代所有細胞同時被以上規則處理後, 可以得到下一代細胞圖。按規則繼續處理這一代的細胞圖,可以得到再下一代的細胞圖,周而復始。


例如假設初始是:(X代表活細胞,.代表死細胞)
.....
.....
.XXX.
.....


下一代會變為:
.....
..X..
..X..
..X..
.....


康威生命遊戲中會出現一些有趣的模式。例如穩定不變的模式:


....
.XX.
.XX.
....


還有會迴圈的模式:


......      ......       ......
.XX...      .XX...       .XX...
.XX...      .X....       .XX...
...XX.   -> ....X.  ->   ...XX.
...XX.      ...XX.       ...XX.
......      ......       ......




本題中我們要討論的是一個非常特殊的模式,被稱作"Gosper glider gun":


......................................
.........................X............
.......................X.X............
.............XX......XX............XX.
............X...X....XX............XX.
.XX........X.....X...XX...............
.XX........X...X.XX....X.X............
...........X.....X.......X............
............X...X.....................
.............XX.......................
......................................


假設以上初始狀態是第0代,請問第1000000000(十億)代一共有多少活著的細胞?


注意:我們假定細胞機在無限的2D網格上推演,並非只有題目中畫出的那點空間。
當然,對於遙遠的位置,其初始狀態一概為死細胞。


注意:需要提交的是一個整數,不要填寫多餘內容。


答案:166666713


第0代 36個


對比前一代細胞數目,發現規律
3,4,5,3,-7,7,-3,13,-19,6,2,4,1,1,-14,2,3,6,1,0,0,-5,11,-17,7,-3,0,3,-2,-7


//找規律
import java.util.ArrayList;


public class Main {
public static void main(String[] args) {
String string[]={
".........................X............",
".......................X.X............",
".............XX......XX............XX.",
"............X...X....XX............XX.",
".XX........X.....X...XX...............",
".XX........X...X.XX....X.X............",
"...........X.....X.......X............",
"............X...X.....................",
".............XX.......................",
};
int n=999,z=n/2;
boolean[][] b = new boolean[n][n];
ArrayList<Integer> lie = new ArrayList<Integer>();
ArrayList<Integer> hang = new ArrayList<Integer>();
int x=0;
for(int i=0;i<string.length;i++)
for(int j=0;j<string[i].length();j++)
{
if(string[i].charAt(j)=='X'){
x++;
lie.add(i+z);
hang.add(j+z);
b[i+z][j+z]=true;
}
}
System.out.println(x);
for(int k=0;k<1000000000;k++)
{
int y=0;
boolean[][] newb = new boolean[n][n];
ArrayList<Integer> newlie = new ArrayList<Integer>();
ArrayList<Integer> newhang = new ArrayList<Integer>();
for(int q=0;q<lie.size();q++)
{
int l=lie.get(q),h=hang.get(q);
int s=0;
for(int i=l-1;i<=l+1;i++)
for(int j=h-1;j<=h+1;j++)
{
if(i==l&&j==h)continue;
if(b[i][j])s++;
else{
int s0=0;
for(int i0=i-1;i0<=i+1;i0++)
for(int j0=j-1;j0<=j+1;j0++)
{
if(i0==i&&j0==j)continue;
if(b[i0][j0])s0++;
}
if(s0==3)
{
if(!newb[i][j])
{
y++;
newb[i][j]=true;
newlie.add(i);
newhang.add(j);
}
}
}
}
if(s==2||s==3)
{
y++;
newb[l][h]=true;
newlie.add(l);
newhang.add(h);
}
}
b=newb;
lie=newlie;
hang=newhang;
//System.out.println(y+" "+(y-x));
System.out.print((y-x)+",");
x=y;
}

}
}


//查詢
public class Main {
public static void main(String[] args) {
int a=36;
int g[]={3,4,5,3,-7,7,-3,13,-19,6,2,4,1,1,-14,2,3,6,1,0,0,-5,11,-17,7,-3,0,3,-2,-7};
int i=0;
for(int k=0;k<1000000000;k++)
{
a+=g[i];
i++;
if(i==g.length)i=0;
}
System.out.println(a);
}

}




標題:樹形顯示


對於分類結構可以用樹形來形象地表示。比如:檔案系統就是典型的例子。


樹中的結點具有父子關係。我們在顯示的時候,把子項向右縮排(用空格,不是tab),並新增必要的連線線,以使其層次關係更醒目。


下面的程式碼就是為了這個目的的,請仔細閱讀原始碼,並填寫劃線部分缺少的程式碼。




import java.util.*;


class MyTree
{
private Map<String, List<String>>  map_ch = new HashMap<String, List<String>>();
private Map<String,String> map_pa = new HashMap<String,String>();

public void add(String parent, String child)
{
map_pa.put(child, parent);

List<String> lst = map_ch.get(parent);
if(lst==null){
lst = new ArrayList<String>();
map_ch.put(parent, lst);
}
lst.add(child);
}

public String get_parent(String me){
return map_pa.get(me);
}

public List<String> get_child(String me){
return map_ch.get(me);
}

private String space(int n)
{
String s = "";
for(int i=0; i<n; i++) s += ' ';
return s;
}

private boolean last_child(String x){
String pa = map_pa.get(x);
if(pa==null) return true;

List<String> lst = map_ch.get(pa);
return lst.get(lst.size()-1).equals(x);
}

public void show(String x){

String s = "+--" + x;

String pa = x;
while(true){
pa = map_pa.get(pa);
if(pa==null) break;
s = ___________________________________ ;  // 填空
}

System.out.println(s);
}

public void dfs(String x){
show(x);

List<String> lst = map_ch.get(x);
if(lst==null) return;

for(String it: lst){
dfs(it);
}
}
}


public class TreeView
{
public static void main(String[] args)
{
MyTree tree = new MyTree();
tree.add("root", "dog");
tree.add("root", "cat");
tree.add("root", "duck");
tree.add("dog", "AAdog");
tree.add("dog", "BBdog");
tree.add("dog", "CCdog");
tree.add("AAdog", "AAdog01");
tree.add("AAdog", "AAdog02");
tree.add("cat", "XXcat");
tree.add("cat", "YYcat");
tree.add("XXcat","XXcat-oo");
tree.add("XXcat","XXcat-qq");
tree.add("XXcat-qq", "XXcat-qq-hahah");
tree.add("duck", "TTduck");
tree.add("TTduck", "TTduck-001");
tree.add("TTduck", "TTduck-002");
tree.add("TTduck", "TTduck-003");
tree.add("YYcat","YYcat.hello");
tree.add("YYcat","YYcat.yes");
tree.add("YYcat","YYcat.me");

tree.dfs("root");
}
}


對於題目中的測試資料,輸出結果:
+--root
     +--dog
     |    +--AAdog
     |    |    +--AAdog01
     |    |    +--AAdog02
     |    +--BBdog
     |    +--CCdog
     +--cat
     |    +--XXcat
     |    |    +--XXcat-oo
     |    |    +--XXcat-qq
     |    |         +--XXcat-qq-hahah
     |    +--YYcat
     |         +--YYcat.hello
     |         +--YYcat.yes
     |         +--YYcat.me
     +--duck
          +--TTduck
               +--TTduck-001
               +--TTduck-002
               +--TTduck-003
  
如有平字型對齊問題,可以參見圖【p1.png】


注意,只填寫劃線部分缺少的程式碼,不要抄寫已有的程式碼或符號。


答案:s = (last_child(pa)?" ":"|")+"    "+s ;



標題:小計算器


模擬程式型計算器,依次輸入指令,可能包含的指令有


1. 數字:'NUM X',X為一個只包含大寫字母和數字的字串,表示一個當前進位制的數
2. 運算指令:'ADD','SUB','MUL','DIV','MOD',分別表示加減乘,除法取商,除法取餘
3. 進位制轉換指令:'CHANGE K',將當前進位制轉換為K進位制(2≤K≤36)
4. 輸出指令:'EQUAL',以當前進位制輸出結果
5. 重置指令:'CLEAR',清除當前數字


指令按照以下規則給出:
數字,運算指令不會連續給出,進位制轉換指令,輸出指令,重置指令有可能連續給出
運算指令後出現的第一個數字,表示參與運算的數字。且在該運算指令和該數字中間不會出現運算指令和輸出指令
重置指令後出現的第一個數字,表示基礎值。且在重置指令和第一個數字中間不會出現運算指令和輸出指令
進位制轉換指令可能出現在任何地方


運算過程中中間變數均為非負整數,且小於2^63。
以大寫的'A'~'Z'表示10~35


[輸入格式]
第1行:1個n,表示指令數量
第2..n+1行:每行給出一條指令。指令序列一定以'CLEAR'作為開始,並且滿足指令規則


[輸出格式]
依次給出每一次'EQUAL'得到的結果


[樣例輸入]
7
CLEAR
NUM 1024
CHANGE 2
ADD
NUM 100000
CHANGE 8
EQUAL


[樣例輸出]
2040


補充說明:
1. n 值範圍: 1<= n < 50000
2. 初始預設的進位制是十進位制






資源約定:
峰值記憶體消耗 < 256M
CPU消耗  < 1000ms




請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入...” 的多餘內容。


所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
注意:不要使用package語句。不要使用jdk1.7及以上版本的特性。
注意:主類的名字必須是:Main,否則按無效程式碼處理。


import java.util.Scanner;


public class Main
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int jinZhi = 10;
int x = 0;
String yunSuan = "ADD";
scanner.nextLine();
for(int i=0;i<n;i++)
{
String string = scanner.nextLine();
if(string.indexOf("CLEAR")!=-1)x=0;
else if(string.indexOf("NUM")!=-1){
string = string.split(" ")[1];
if(yunSuan.indexOf("ADD")!=-1)x += Integer.parseInt(string, jinZhi);
else if(yunSuan.indexOf("SUB")!=-1)x -= Integer.parseInt(string, jinZhi);
else if(yunSuan.indexOf("MUL")!=-1)x *= Integer.parseInt(string, jinZhi);
else if(yunSuan.indexOf("DIV")!=-1)x /= Integer.parseInt(string, jinZhi);
else if(yunSuan.indexOf("MOD")!=-1)x %= Integer.parseInt(string, jinZhi);
}
else if(string.indexOf("ADD")!=-1)
{
yunSuan = "ADD";
}
else if(string.indexOf("SUB")!=-1)
{
yunSuan = "SUB";
}
else if(string.indexOf("MUL")!=-1)
{
yunSuan = "MUL";
}
else if(string.indexOf("DIV")!=-1)
{
yunSuan = "DIV";
}
else if(string.indexOf("MOD")!=-1)
{
yunSuan = "MOD";
}
else if(string.indexOf("CHANGE")!=-1)
{
string = string.split(" ")[1];
jinZhi = Integer.parseInt(string);
}
else if(string.indexOf("EQUAL")!=-1)
{
System.out.println(Integer.toString(x, jinZhi));
}
else if(string.indexOf("CLEAR")!=-1)
{
x=0;
yunSuan="ADD";
}
}
}

}


標題:填字母遊戲


小明經常玩 LOL 遊戲上癮,一次他想挑戰K大師,不料K大師說:
“我們先來玩個空格填字母的遊戲,要是你不能贏我,就再別玩LOL了”。


K大師在紙上畫了一行n個格子,要小明和他交替往其中填入字母。


並且:


1. 輪到某人填的時候,只能在某個空格中填入L或O
2. 誰先讓字母組成了“LOL”的字樣,誰獲勝。
3. 如果所有格子都填滿了,仍無法組成LOL,則平局。


小明試驗了幾次都輸了,他很慚愧,希望你能用計算機幫他解開這個謎。


本題的輸入格式為:
第一行,數字n(n<10),表示下面有n個初始局面。
接下來,n行,每行一個串,表示開始的局面。
  比如:“******”, 表示有6個空格。
  “L****”,   表示左邊是一個字母L,它的右邊是4個空格。


要求輸出n個數字,表示對每個局面,如果小明先填,當K大師總是用最強著法的時候,小明的最好結果。
1 表示能贏
-1 表示必輸
0 表示可以逼平




例如,
輸入:
4
***
L**L
L**L***L
L*****L


則程式應該輸出:
0
-1
1
1


資源約定:
峰值記憶體消耗 < 256M
CPU消耗  < 1000ms




請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入...” 的多餘內容。


所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
注意:不要使用package語句。不要使用jdk1.7及以上版本的特性。
注意:主類的名字必須是:Main,否則按無效程式碼處理。


import java.util.Scanner;


public class Main
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
scanner.nextLine();
for(int i=0;i<n;i++)
{
String string = scanner.nextLine();
int a = 0; //0小明 1k
while(string.indexOf("*")!=-1)
{
if(ying(string)){
if(a==0)System.out.println(1);
else if(a==1)System.out.println(-1);
break;
}
int num=-1;
String newstring = null;
do
{
num = string.indexOf("*",num+1);
if(num==-1)break;
newstring = string.substring(0, num)+"L"+string.substring(num+1, string.length());
if(ying(newstring))
newstring = string.substring(0, num)+"O"+string.substring(num+1, string.length());
if(!ying(newstring)){
string = newstring;
break;
}
}while(num!=-1);
if(num==-1)
string = newstring;
if(a==0)a=1;
else if(a==1)a=0;
}
if(string.indexOf("*")==-1)System.out.println(0);
}
}
static boolean ying(String string)
{
if(string.indexOf("*OL")!=-1||string.indexOf("LO*")!=-1||string.indexOf("L*L")!=-1)
{
return true;
}
return false;
}

}



標題:區間移位


數軸上有n個閉區間:D1,...,Dn。
其中區間Di用一對整數[ai, bi]來描述,滿足ai < bi。
已知這些區間的長度之和至少有10000。
所以,通過適當的移動這些區間,你總可以使得他們的“並”覆蓋[0, 10000]——也就是說[0, 10000]這個區間內的每一個點都落於至少一個區間內。
你希望找一個移動方法,使得位移差最大的那個區間的位移量最小。


具體來說,假設你將Di移動到[ai+ci, bi+ci]這個位置。你希望使得maxi{|ci|} 最小。


【輸入格式】
輸入的第一行包含一個整數n,表示區間的數量。
接下來有n行,每行2個整數ai, bi,以一個空格分開,表示區間[ai, bi]。
保證區間的長度之和至少是10000。


【輸出格式】
輸出一個數字,表示答案。如果答案是整數,只輸出整數部分。如果答案不是整數,輸出時四捨五入保留一位小數。


【樣例輸入】
2
10 5010
4980 9980


【樣例輸出】
20


【樣例說明】
第一個區間往左移動10;第二個區間往右移動20。


【樣例輸入】
4
0 4000
3000 5000
5001 8000
7000 10000
【樣例輸出】
0.5
【樣例說明】
第2個區間往右移0.5;第3個區間往左移0.5即可。


【資料規模與約定】
對於30%的評測用例,1 <= n <= 10;
對於100%的評測用例,1 <= n <= 10000,0 <= ai < bi <= 10000。


資源約定:
峰值記憶體消耗 < 256M
CPU消耗  < 2000ms




請嚴格按要求輸出,不要畫蛇添足地列印類似:“請您輸入...” 的多餘內容。


所有程式碼放在同一個原始檔中,除錯通過後,拷貝提交該原始碼。
注意:不要使用package語句。不要使用jdk1.7及以上版本的特性。
注意:主類的名字必須是:Main,否則按無效程式碼處理。


import java.util.ArrayList;
import java.util.Scanner;


public class Main
{
public static void main(String[] args)
{
Scanner scanner = new Scanner(System.in);
ArrayList<Integer> a = new ArrayList<Integer>();
ArrayList<Integer> b = new ArrayList<Integer>();
int n = scanner.nextInt();
int mini = 0,maxi = 0;
int min = 10000,max = 0;
for(int i=0;i<n;i++)
{
int temp = scanner.nextInt();
a.add(temp);
if(temp<min){
mini=i;
min=temp;
}
temp = scanner.nextInt();
b.add(temp);
if(temp>max){
maxi=i;
max = temp;
}
}
int left=0,right=10000;
float yimax=0;
while(left<right)
{
int l=left,r=right;

int yi = min-left;
int yi1;
if(yi>=0){
yi1=yi;
}else{
yi1=yi*(-1);
}
left = b.get(mini)-yi;

yi = right - max;
int yi2 ;
if(yi>=0){
yi2=yi;
}else{
yi2=yi*(-1);
}
right = a.get(maxi)+yi;

if(right<left)
{
float p = a.get(maxi);
float q = b.get(mini);
float j = (p-q)/2;
float zuo = a.get(mini)+j;
float you = b.get(maxi)-j;
if(zuo>l)
{
j+=(zuo-l);
}else if(you<r)
{
j+=(r-you);
}
if(j<yi1&&j<yi2){
if(yimax<j)
yimax=j;
}
else if(yi1>=yi2){
if(yi1>yimax)
yimax=yi1;
}
else if(yi1<yi2){
if(yi2>yimax)
yimax=yi2;
}
}else
{
if(yi1>=yi2){
if(yi1>yimax)
yimax=yi1;
}
else if(yi1<yi2){
if(yi2>yimax)
yimax=yi2;
}
}

a.remove(mini);
b.remove(mini);
if(maxi!=mini)
{
if(maxi>mini)maxi--;
a.remove(maxi);
b.remove(maxi);
}
if(a.size()==0)break;
mini=0;
maxi=0;
int minju = Math.abs(a.get(0)-left);
int maxju = Math.abs(b.get(0)-right);
for(int i=1;i<a.size();i++)
{
int temp = Math.abs(a.get(i)-left);
if(temp<minju){
minju=temp;
mini=i;
}
temp = Math.abs(b.get(i)-right);
if(temp<maxju){
maxju=temp;
maxi=i;
}
}
min = a.get(mini);
max = b.get(maxi);
}
if(yimax-(int)yimax==0)System.out.print((int)yimax);
else System.out.printf("%.1f",yimax);
}
}