2017年4月藍橋杯模擬題


1、標題:算年齡


英國數學家德摩根出生於19世紀初葉(即18xx年)。
他年少時便很有才華。一次有人問他的年齡,他回答說:
“到了x的平方那年,我剛好是x歲”。
請你計算一下,德摩根到底出生在哪一年。
題中的年齡指的是周歲。

請填寫表示他出生年份的四位數字,不要填寫任何多余內容。

思路:

設當前是x(1=<x<=100)歲,求得出生日期是y(1800=<y<=1900),則由題意
x2=那年
那年-y=x;
聯立得:x2-y=x

注意結果為兩個值一個1806年是43歲,一個1892年是44歲

但是填空肯定只能填一個,根據19世紀初葉選擇了1806年

結果為:1806

代碼:

 1 public class _1算年齡 {
 2     public static void main(String[] args) {
 3         for (int i = 1; i < 100; i++) {
 4             for (int j = 1800; j < 1900; j++) {
 5                 if (i*i - j ==i) {
 6                     System.out.println(j);
 7                     //System.out.println(i);測試輸出一下年齡
 8                 }
 9             }
10         }
11     }
12 }

 


2、題目:猜算式

你一定還記得小學學習過的乘法計算過程,比如:
   179
x  224
------
   716
 358
358
------
40096 
請你觀察如下的乘法算式

    ***
x   ***
--------
    ***
   ***
  ***
--------
  *****
  
星號代表某位數字,注意這些星號中,
0~9中的每個數字都恰好用了2次。
(如因字體而產生對齊問題,請參看圖p1.jpg)

請寫出這個式子最終計算的結果,就是那個5位數是多少?


注意:只需要填寫一個整數,不要填寫任何多余的內容。比如說明文字。

思路:

1、a,b為兩個乘數,分別大於等於100小於1000,進行循環
2、依次算出a乘以b的每位的結果c,d,e,在c+d*10+e*100=f;
3、判斷f的范圍大於等於10000小於100000
4、將abcdef組成一個字符串,進行排序,若排出的結果為00112233445566778899則輸出f

結果為:40096

代碼:

 1 public class _2猜算式 {
 2     public static void main(String[] args) {
 3         String string="";
 4         for (int a = 100; a < 1000; a++) {
 5             for (int b = 100; b < 1000; b++) {
 6                 int c = a*(b%10);//a*b的個位
 7                 int d = a*(b/10%10);//a*b的十位
 8                 int e = a*(b/100);//a*b的百位
 9                 int f = c+d*10+e*100;
10                 if (f>=10000&&f<100000) {
11                     string = ""+a+b+c+d+e+f;
12                     char[] ch = string.toCharArray();
13                     Arrays.sort(ch);
14                     if (new String(ch).equals("00112233445566778899")) {
15                         //System.out.println(a+"##"+b+"##"+c+"##"+d+"##"+e+"##"+f);//測試輸出所有數字
16                         System.out.println(f);
17                     }
18                 }
19             }
20         }
21     }
22     
23 }

 


3、標題: 排列序數

X星系的某次考古活動發現了史前智能痕跡。
這是一些用來計數的符號,經過分析它的計數規律如下:
(為了表示方便,我們把這些奇怪的符號用a~q代替)

abcdefghijklmnopq 表示0
abcdefghijklmnoqp 表示1
abcdefghijklmnpoq 表示2
abcdefghijklmnpqo 表示3
abcdefghijklmnqop 表示4
abcdefghijklmnqpo 表示5
abcdefghijklmonpq 表示6
abcdefghijklmonqp 表示7
.....


在一處石頭上刻的符號是:
bckfqlajhemgiodnp


請你計算出它表示的數字是多少?


請提交該整數,不要填寫任何多余的內容,比如說明或注釋。

答案:22952601027516

思路1因為是填空題,可以用數學進行計算:

想到了字母的全排列可能對應相應的數字,但是一有17個字母,代碼都跑不起來,之后去百度了一下,發現了“康托展開式”

康托展開的公式是 X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+a2*1!+a1*0! 其中,ai為當前未出現的元素中是排在第幾個(從0開始)。

舉個例子說明:數組 s = ["A", "B", "C", "D"],它的一個排列 s1 = ["D", "B", "A", "C"],現在要求DBAC代表的是數字幾。

n 指的是數組的長度,也就是4,所以X(s1) = a4*3! + a3*2! + a2*1! + a1*0!  關鍵問題是 a4、a3、a2 和 a1 等於什么?

a4 = "D" 這個元素在子數組 ["D", "B", "A", "C"] 中是第幾大的元素。"A"是第0大的元素,"B"是第1大的元素,"C" 是第2大的元素,"D"是第3大的元素,所以 a4 = 3

a3 = "B" 這個元素在子數組 ["B", "A", "C"] 中是第幾大的元素。"A"是第0大的元素,"B"是第1大的元素,"C" 是第2大的元素,所以 a3 = 1。

a2 = "A" 這個元素在子數組 ["A", "C"] 中是第幾大的元素。"A"是第0大的元素,"C"是第1大的元素,所以 a2 = 0。

a1 = "C" 這個元素在子數組 ["C"] 中是第幾大的元素。"C" 是第0大的元素,所以 a1 = 0。(因為子數組只有1個元素,所以a1總是為0)

所以,X(s1) = 3*3! + 1*2! + 0*1! + 0*0! = 20

根據題目的字符串bckfqlajhemgiodnp

則x=a17*16! +a16*15! +a15*14! +a14*13! +a13*12! +a12*11! + a11*10! +a10*9! +a9*8! +a8*7! +a7*6! +a6*5! +a5*4! +a4*3! +a3*2! +a2*1! +a1*0!

其中a17=b=1  a16=c=1  a15=k=8  a14=f=3  a13=q=12  a12=l=7  a11=a=0  a10=j=5  a9=h=3  a8=e=1  a7=m=3  a6=g=1  a5=i=1  a4=o=2  a3=d=0  a2=n=0  a1=p=0

所以x=1*16!+1*15!+8*14!+3*13!+12*12!+7*11!+0*10!+5*9!+3*8!+1*7!+3*6!+1*5!+1*4!+2*3!+0*2!+0*1!+0*0!

        =22952601027516

 

思路2運用編程

代碼:

 1 public class _3排列序數 {
 2     public static void main(String[] args) {
 3             String s="bckfqlajhemgiodnp";//bckfqlajhemgiodnp  
 4                  System.out.println(s);  
 5                  int[] arr = quanzhi(s);  
 6                 long sum=0;  
 7                 for (int i = arr.length-1,k=0; i >=0; i--,k++) {  
 8                 sum+=arr[i]*jiecheng(k);  
 9                }  
10                 System.out.println(sum);  
11             }  
12              private static int[] quanzhi(String s) {  
13                  int[] arr=new int[s.length()];  
14                    
15                  for (int i = 0; i < arr.length; i++) {  
16                     int q=0;  
17                      for (int j = i+1; j < arr.length; j++) {  
18                         if(s.charAt(i)-s.charAt(j)>0){  
19                              q++;  
20                          }  
21                      }  
22                      arr[i]=q;  
23                  }  
24                    
25                  return arr;  
26              }  
27              private static long jiecheng(long l) {  
28                  if(l==0||l==1){  
29                      return 1;  
30                  }  
31                  long j=1;  
32                  for (int i = 1; i <=l; i++) {  
33                      j=j*i;  
34                  }  
35                  return j;  
36     }
37 }

 


4、標題:字符串比較


我們需要一個新的字符串比較函數compare(s1, s2).
對這個函數要求是:
1. 它返回一個整數,表示比較的結果。
2. 結果為正值,則前一個串大,為負值,后一個串大,否則,相同。
3. 結果的絕對值表示:在第幾個字母處發現了兩個串不等。

下面是代碼實現。對題面的數據,結果為:
-3
2
5


仔細閱讀源程序,填寫划線位置缺少的代碼。

-------------------------------------------------
Java語言代碼:

static int compare(String s1, String s2)
{
if(s1==null && s2==null) return 0;
if(s1==null) return -1;
if(s2==null) return 1;

if(s1.isEmpty() && s2.isEmpty()) return 0;
if(s1.isEmpty()) return -1;
if(s2.isEmpty()) return 1;

char x = s1.charAt(0);
char y = s2.charAt(0);

if(x<y) return -1;
if(x>y) return 1;

int t = compare(s1.substring(1),s2.substring(1));
if(t==0) return 0;

return ____________________ ; //填空位置
}


public static void main(String[] args)
{
System.out.println(compare("abc", "abk"));
System.out.println(compare("abc", "a"));
System.out.println(compare("abcde", "abcda"));
}

注意:
只提交划線部分缺少的代碼,不要包含已經存在的代碼或符號。
也不要畫蛇添足地寫出任何注釋或說明性文字。

注意選擇你所使用的語言。

 1 public class T4 {  
 2     static int compare(String s1, String s2)  
 3     {  
 4         if(s1==null && s2==null) return 0;  
 5         if(s1==null) return -1;  
 6         if(s2==null) return 1;  
 7           
 8         if(s1.isEmpty() && s2.isEmpty()) return 0;  
 9         if(s1.isEmpty()) return -1;  
10         if(s2.isEmpty()) return 1;  
11           
12         char x = s1.charAt(0);  
13         char y = s2.charAt(0);  
14           
15         if(x<y) return -1;  
16         if(x>y) return 1;  
17           
18         int t = compare(s1.substring(1),s2.substring(1));  
19         if(t==0) return 0;  
20           
21         return t>0?(1+(t>0?t++:t--)):(-1+(t>0?t--:t++)); //填空位置//1+(t==0?(t++):(t--))  
22     }  
23   
24     public static void main(String[] args)  
25     {  
26         System.out.println(compare("abc", "abk"));  
27         System.out.println(compare("abc", "a"));  
28         System.out.println(compare("abcde", "abcda"));                
29     }  
30 }  

5、標題: 還款計算

銀行貸款的等額本息還款方法是:
每月還固定的金額,在約定的期數內正好還完(最后一個月可能會有微小的零頭出入)。

比如說小明在銀行貸款1萬元。貸款年化利率為5%,貸款期限為24個月。
則銀行會在每個月進行結算:
結算方法是:計算本金在本月產生的利息: 本金 x (年利率/12)
則本月本金結余為:本金 + 利息 - 每月固定還款額
計算結果會四舍五入到“分”。

經計算,此種情況下,固定還款額應為:438.71

這樣,第一月結算時的本金余額是:
9602.96
第二個月結算:
9204.26
第三個月結算:
8803.9
....
最后一個月如果仍按固定額還款,則最后仍有0.11元的本金余額,
但如果調整固定還款額為438.72, 則最后一個月會多還了銀行0.14元。
銀行會選擇最后本金結算絕對值最小的情況來設定 每月的固定還款額度。
如果有兩種情況最后本金絕對值相同,則選擇還款較少的那個方案。


本題的任務是已知年化利率,還款期數,求每月的固定還款額度。


假設小明貸款為1萬元,即:初始本金=1萬元。
年化利率的單位是百分之多少。
期數的單位為多少個月。


輸入為2行,
第一行為一個小數r,表示年率是百分之幾。(0<r<30)
第二行為一個整數n,表示還款期限。 (6<=n<=120)

要求輸出為一個整數,表示每月還款額(單位是:分)

例如:
輸入:
4.01
24

程序應該輸出:
43429

再比如:
輸入:
6.85
36

程序應該輸出:
30809

補充:Bigdecimal.setScale()

BigDecimal.setScale()方法用於格式化小數點
// setScale(1)表示保留一位小數,默認用四舍五入方式
// setScale(1,BigDecimal.ROUND_DOWN)直接刪除多余的小數位,如2.35會變成2.3
// setScale(1,BigDecimal.ROUND_UP)進位處理,2.35變成2.4
// setScale(1,BigDecimal.ROUND_HALF_UP)四舍五入,2.35變成2.4
// setScaler(1,BigDecimal.ROUND_HALF_DOWN)四舍五入,2.35變成2.3,如果是5則向下舍


代碼:

 1 import java.util.Scanner;  
 2 import java.math.BigDecimal;  
 3   
 4 public class T5 {  
 5   
 6     public static void main(String[] args) {  
 7           
 8         Scanner sc=new Scanner(System.in);  
 9         double lv=sc.nextDouble()/100;  
10         double m=sc.nextDouble();  
11           
12         double ed=0,sy=100;  
13         double x=10000/m;//怎么確定一個大概的范圍??  
14         for (double k = x; k < x+50; k+=0.01) {  
15               
16             double d=10000;  
17               
18             BigDecimal kk=BigDecimal.valueOf(k);  
19             k=kk.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();  
20               
21             for (int i = 1; i <= m; i++) {  
22                 BigDecimal bd=BigDecimal.valueOf(d+d*(lv/12)-k);  
23                 d=bd.setScale(2,BigDecimal.ROUND_HALF_UP).doubleValue();  
24             }  
25             if(Math.abs(sy-d)<sy){  
26                 ed=k;  
27                 sy=d;  
28                 //System.out.println(k+": "+d);  
29             }  
30         }     
31         System.out.println((int)(ed*100));  
32     }  
33 }  

6、題目:滑動解鎖

滑動解鎖是智能手機一項常用的功能。你需要在3x3的點陣上,從任意一個點開始,反復移動到一個尚未經過的"相鄰"的點。這些划過的點所組成的有向折線,如果與預設的折線在圖案、方向上都一致,那么手機將解鎖。

所謂兩個點“相鄰”:當且僅當以這兩個點為端點的線段上不存在尚未經過的點。

此外,許多手機都約定:這條折線還需要至少經過4個點。

為了描述方便,我們給這9個點從上到下、從左到右依次編號1-9。即如下排列:

1 2 3
4 5 6
7 8 9

那么1->2->3是非法的,因為長度不足。
1->3->2->4也是非法的,因為1->3穿過了尚未經過的點2。
2->4->1->3->6是合法的,因為1->3時點2已經被划過了。

某大神已經算出:一共有389112種不同的解鎖方案。沒有任何線索時,要想暴力解鎖確實很難。
不過小Hi很好奇,他希望知道,當已經瞥視到一部分折線的情況下,有多少種不同的方案。
遺憾的是,小Hi看到的部分折線既不一定是連續的,也不知道方向。

例如看到1-2-3和4-5-6,
那么1->2->3->4->5->6,1->2->3->6->5->4, 3->2->1->6->5->4->8->9等都是可能的方案。

你的任務是編寫程序,根據已經瞥到的零碎線段,求可能解鎖方案的數目。

輸入:
每個測試數據第一行是一個整數N(0 <= N <= 8),代表小Hi看到的折線段數目。
以下N行每行包含兩個整數 X 和 Y (1 <= X, Y <= 9),代表小Hi看到點X和點Y是直接相連的。

輸出:
對於每組數據輸出合法的解鎖方案數目。

例如:
輸入:
8
1 2
2 3
3 4
4 5
5 6
6 7
7 8
8 9

程序應該輸出:
2

再例如:
輸入:
4
2 4
2 5
8 5
8 6

程序應該輸出:
258

資源約定:
峰值內存消耗(含虛擬機) < 256M
CPU消耗  < 1000ms

 

代碼:

 1 import java.util.Scanner;  
 2 public class _6手機滑動解鎖 {
 3     static boolean[][] a = new boolean[10][10];//記錄不可能出現的情況,共有八種
 4     static boolean[] b = new boolean[10];//已經用過的點
 5     static int sum;//總的解鎖方案數目
 6     static int n;//折線段數目
 7     static int[][] c;//已知線段
 8     static int[] d = new int[11];//搜索出來的點
 9     public static void main(String[] args) {
10         Scanner input = new Scanner(System.in);
11         a[1][3] = true;
12         a[1][7] = true;
13         a[1][9] = true;
14         a[2][8] = true;
15         a[3][9] = true;
16         a[3][7] = true;
17         a[4][6] = true;
18         a[7][9] = true;
19         n = input.nextInt();
20         c = new int[n][2];
21         for(int i=0;i<n;i++){
22             c[i][0] = input.nextInt();
23             c[i][1] = input.nextInt();
24         }
25         f(1,1);
26         System.out.println(sum);
27     }
28     //檢查i是否被搜索過
29     public static boolean  check(int i){
30         int j,k;
31         for(j=0;j<n;j++){
32             for(k=1;k<=i;k++){
33                 if(d[k]==c[j][0]||d[k]==c[j][1]){
34                     if(d[k]==c[j][0]){
35                         if(d[k-1]==c[j][1])    break;
36                     }else{
37                         if(d[k-1]==c[j][0])    break;
38                     }
39                 }
40             }
41             if(k>i)    return false;
42         }
43         return true;
44     }
45     public static void f(int i,int h){
46         if(i>4){
47             if(check(i-1))
48             sum++;
49         }
50         if(i>9) return;
51         
52         for(int j=1;j<=9;j++){
53             if(b[j]!=true){
54                 if(i>1){
55                     if(a[h][j]!=true&&a[j][h]!=true){
56                         b[j] = true;
57                         d[i] = j;
58                         f(i+1,j);
59                         b[j] = false;
60                     }else if(b[(h+j)/2]){
61                         d[i] = j;
62                         b[j] = true;
63                         f(i+1,j);
64                         b[j] = false;
65                     }
66                 }else{
67                     d[i] = j;
68                     b[j] = true;
69                     f(i+1,j);
70                     b[j] = false;
71                 }
72             }
73             
74         }
75     }
76 }

 


7、標題:風險度量

X星系的的防衛體系包含 n 個空間站。這 n 個空間站間有 m 條通信鏈路,構成通信網。
兩個空間站間可能直接通信,也可能通過其它空間站中轉。

對於兩個站點x和y (x != y), 如果能找到一個站點z,使得:
當z被破壞后,x和y無法通信,則稱z為關於x,y的關鍵站點。

顯然,對於給定的兩個站點,關於它們的關鍵點的個數越多,通信風險越大。

你的任務是:已知網絡結構,求兩站點之間的通信風險度,即:它們之間的關鍵點的個數。

輸入數據第一行包含2個整數n(2 <= n <= 1000), m(0 <= m <= 2000),分別代表站點數,鏈路數。
空間站的編號從1到n。通信鏈路用其兩端的站點編號表示。
接下來m行,每行兩個整數 u,v (1 <= u, v <= n; u != v)代表一條鏈路。
最后1行,兩個數u,v,代表被詢問通信風險度的兩個站點。

輸出:一個整數,如果詢問的兩點不連通則輸出-1.

例如:
用戶輸入:
7 6
1 3
2 3
3 4
3 5
4 5
5 6
1 6

則程序應該輸出:
2

資源約定:
峰值內存消耗(含虛擬機) < 256M
CPU消耗  < 2000ms

 

代碼:

 1 import java.util.Scanner;  
 2   
 3 public class T7 {  
 4   
 5     static boolean[][] data;  
 6     static boolean[] vis;  
 7     static boolean fal=false;  
 8       
 9     public static void main(String[] args) {  
10           
11         Scanner sc=new Scanner(System.in);  
12           
13         int n=sc.nextInt();  
14         int m=sc.nextInt();  
15           
16         data=new boolean[n+1][n+1];  
17         int[] arr=new int[n+1];  
18         vis=new boolean[n+1];  
19           
20         for (int i = 1; i < arr.length; i++) {  
21             arr[i]=i;  
22         }  
23           
24         //標記走得通得路線  
25         for (int i = 0; i < m; i++) {  
26             int a=sc.nextInt();  
27             int b=sc.nextInt();  
28             data[a][b]=data[b][a]=true;  
29         }  
30           
31         int begin=sc.nextInt();  
32         int end=sc.nextInt();  
33         sc.close();  
34           
35         //先看從begin到end走得通嗎  
36         vis[0]=true;  
37         dfs(begin,end,0);  
38         if(!fal){  
39             System.out.println("-1");  
40             return;  
41         }  
42         //System.out.println("OK");  
43           
44         //走得通,遍歷去除每一個點  
45         int count=0;  
46         for (int i = 1; i < arr.length; i++) {  
47             if(arr[i]!=begin&&arr[i]!=end)  
48             fal=false;  
49             dfs(begin,end,arr[i]);  
50             if(fal==false)  
51                 count++;  
52         }  
53           
54         System.out.println(count);  
55     }  
56   
57     private static void dfs(int begin, int end, int i) {  
58           
59         //System.out.println(begin+" "+end+" "+data[begin][end]);  
60         if(data[begin][end]==true){  
61             fal=true;  
62             return;  
63         }  
64   
65         for (int j = 1; j < data.length; j++) {  
66             if(j!=i&&!vis[begin]&&data[begin][j]==true){  
67                 vis[begin]=true;  
68                 dfs(j,end,i);  
69                 vis[begin]=false;  
70             }  
71         }  
72         return;  
73     }  
74 }  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM