藍橋杯備賽算法(java)


導學

藍橋杯課程安排:

 

 

 

 參考書籍:

 

 學習方法:

 

 

位運算

 

 

 

 

 

1-1000這1000個數放在含有1001個元素的數組中,只有唯一的一個元素值重復,其它均只出現一次。
每個數組元素只能訪問一次,設計一個算法,將它找出來;不用輔助存儲空間,能否設計一個算法實現?

 

 1 package 算法基礎;
 2 import 算法基礎.數組隨機排序;
 3 import java.util.Random;
 4 
 5 /**
 6  * @Auther:zhushen
 7  * @Date:2021/1/13
 8  * @Description:位運算
 9  * @version:1.0
10  */
11 public class 唯一成對的數 {
12     /*
13     1-1000這1000個數放在含有1001個元素的數組中,只有唯一的一個元素值重復,其它均只出現一次。
14     每個數組元素只能訪問一次,設計一個算法,將它找出來;不用輔助存儲空間,能否設計一個算法實現?
15      */
16     public static void main(String[]args){
17         System.out.println("============方法一============");
18         //不使用輔助存儲空間
19         //思路:將數組元素與正常無重復數組元素進行異或(數組元素為0—10中的整數)
       //異或
20 //代碼實現參考:兩個數交換值 21 //num1 = num1^num2; 22 //num2 = num1^num2; 23 //num1 = num1^num2; 24 int N = 11; 25 int[]arr = new int[N]; 26 //填充整數 27 for (int i =0;i<arr.length-1;i++){ 28 arr[i]=i+1; 29 } 30 //最后一個數,是隨機數 31 arr[arr.length-1]= new Random().nextInt(N-1)+1; 32 //隨機下標 33 數組隨機排序.shuffle(arr); 34 int x1 = 0; 35 for(int i = 1;i<=N-1;i++){ 36 x1 = (x1^i); 37 } 38 for(int i = 0;i<N;i++){ 39 x1 = x1^arr[i]; 40 } 41 for (int value : arr) { 42 System.out.print(value); 43 } 44 System.out.println("\n"+x1); 45 46 System.out.println("============方法二============"); 47 //使用輔助存儲空間 48 //思路:使用數組下標查出重復元素 49 //代碼實現:使用輔助存儲空間,將該數組的值作為輔助存儲空間(數組)的下標。 50 int[]helper = new int[N]; 51 for (int i=0;i<N;i++){ 52 helper[arr[i]]++;//上一個數組的值作為該數組元素的下標 53 } 54 for (int i=0;i<N;i++){ 55 if(helper[i]==2){ 56 System.out.println(i); 57 break; 58 } 59 } 60 } 61 }
 1 package 算法基礎;
 2 import java.util.Random;
 3 
 4 /**
 5  * @Auther:zhushen
 6  * @Date:2021/1/13
 7  * @Description:tools
 8  * @version:1.0
 9  */
10 public class 數組隨機排序 {
11 
12 
13     /**
14      * 隨機排序
15      */
16 
17         private static Random rand = new Random();
18 
19         public static void swap(int[] a, int i, int j) {
20         int temp = a[i];
21             a[i] = a[j];
22             a[j] = temp;
23         }
24 
25         public static void shuffle(int[] arr) {
26             int length = arr.length;
27             for (int i = length; i > 0; i--) {
28                 int randInd = rand.nextInt(i);
29                 swap(arr, randInd, i - 1);
30             }
31         }
32     }

 

 

 一個數組里除了某一個數字之外,其他的數字都出現了兩次。請寫程序找出這個只出現一次的數字。

 1 package 算法基礎;
 2 
 3 import java.util.Random;
 4 
 5 /**
 6  * @Auther:zhushen
 7  * @Date:2021/1/13
 8  * @Description:位運算
 9  * @version:1.0
10  */
11 public class 找出落單的數 {
12     public static void main(String[] args) {
13         System.out.println("============方法一============");
14         //不使用輔助存儲空間
15         //思路:直接異或,A^A=0、A^0=A
16         //代碼實現參考:兩個數交換值
17         //num1 = num1^num2;
18         //num2 = num1^num2;
19         //num1 = num1^num2;
20         int N = 11;
21         int[]arr = new int[N];
22         //填充整數
23         for (int i =0;i<arr.length-1;i=i+2){
24             arr[i+1]=arr[i]=i+1;
25         }
26         //最后一個數,是隨機數
27         arr[arr.length-1]= new Random().nextInt(N-1)+1;
28         //隨機下標
29         數組隨機排序.shuffle(arr);
30         int x1 = 0;
31         for(int i = 0;i<N;i++){
32             x1 = x1^arr[i];
33         }
34         for (int value : arr) {
35             System.out.print(value);
36         }
37         System.out.println("\n"+x1);
38 
39         System.out.println("============方法二============");
40         //使用輔助存儲空間
41         //思路:使用數組下標查出不重復元素
42         //代碼實現:使用輔助存儲空間,將該數組的值作為輔助存儲空間(數組)的下標。
43         int[]helper = new int[N];
44         for (int i=0;i<N;i++){
45             helper[arr[i]]++;//上一個數組的值作為該數組元素的下標
46         }
47         for (int i=0;i<N;i++){
48             if(helper[i]==1){
49                 System.out.println(i);
50                 break;
51             }
52         }
53     }
54 }

 

請實現一個函數,輸入一個整數,輸出該數二進制表示中1的個數。
例:9的二進制表示為1001,有2位是1

 1 package 算法基礎;
 2 
 3 import java.util.Scanner;
 4 
 5 /**
 6  * @Auther:zhushen
 7  * @Date:2021/1/13
 8  * @Description:位運算
 9  * @version:1.0
10  */
11 public class 二進制中1的個數 {
12     public static void main(String[] args) {
13         System.out.println("請輸入要求的數:");
14         Scanner sc = new Scanner(System.in);
15         int N = sc.nextInt();
16         System.out.println(Integer.toString(N, 2));
17         //方法一:
18         //拿1從右向左與原數字做&運算
19         int count = 0;
20         //對比每一位
21         for (int i = 0; i < 32; i++) {
22             if ((N & (1 << i)) == (1 << i)) {
23                 count++;
24             }
25         }
26         System.out.println(count);
27 
28         //方法二:把原數字往右移與1做&運算
29         count = 0;
30         for(int i = 0;i<32;i++){
31             if(((N>>>i)&1)==1)
32             count++;
33         }
34         System.out.println(count);
35 
36         //方法三:原數字-1,每次可消除一個1,然后原數字與-1后的數字做與運算。
37         //現象(1):1000-1=0111
38         //現象(2):1000&0111=0000
39         count = 0;
40         while(N!=0){
41             N = ((N-1)&N);
42             count++;
43         }
44         System.out.println(count);
45     }
46 }

 

 用一條語句判斷一個整數是不是2的整數次方。

1         int N = 18;
2         System.out.println(Integer.toString(N, 2));
3         if(((N-1)&N)==0){
4             System.out.println("是");
6         }else{
7             System.out.println("不是");
8         } 

 

 1 package 算法基礎;
 2 
 3 import org.junit.Assert;
 4 
 5 /**
 6  * @Auther:zhushen
 7  * @Date:2021/2/5
 8  * @Description:位運算,見一個記一個。
 9  * @version:1.0
10  */
11 public class 整數的奇偶位互換 {
12     public static void main(String[] args) {
13         int a = 0b01000000_00000000_00000000_00000000;
14         int b =m(a);
15         Assert.assertEquals(b,0b10000000_00000000_00000000_00000000);
16     }
17     private static int m(int i){
18         int ou = i&0xaaaaaaaa;//原數字和1010 1010 1010....(偶數位為1,奇數位為0)做與運算取出偶數位
19         int ji = i&0x55555555;//原數字和0101 0101 0101....(偶數位為0,奇數位為1)做與運算取出奇數位
20         return (ou>>1)^(ji<<1);//連起來
21     }
22 }

 

(1)給定一個介於0和1之間的實數,(如0.625),類型為double,打印它的二進制表示(0.101,因為小數點后的二進制分別表示0.5,0.25.0.125......)。

(2)如果該數字無法精確地用32位以內的二進制表示,則打印“ERROR"

 1 package 算法基礎;
 2 
 3 import com.sun.org.apache.bcel.internal.generic.RETURN;
 4 
 5 /**
 6  * @Auther:zhushen
 7  * @Date:2021/2/5
 8  * @Description:位運算,見一個記一個
 9  * @version:1.0
10  */
11 public class 二進制表示浮點實數 {
12     public static void main(String[] args) {
13         double num = 0.625;
14         StringBuilder sb = new StringBuilder("0.");
15         while(num>0){
16             //乘2挪整
17             double r = num*2;
18             //判斷整數部分
19             if(r>=1){
20                 sb.append("1");
21                 //消除整數部分
22                 num=r-1;
23             }else{
24                 sb.append("0");
25                 num = r;
26             }
27             if(sb.length()>34){
28                 System.out.println("ERROR");
29                 return;
30             }
31         }
32         System.out.println(sb.toString());
33     }
34 }

 

 1 package 算法基礎;
 2 
 3 /**
 4  * @Auther:zhushen
 5  * @Date:2021/2/6
 6  * @Description:
 7  * @version:1.0
 8  */
 9 public class 出現k次與1次 {
10     public static void main(String[] args) {
11         int[]arr = {2,2,2,9,7,7,7,3,3,3,6,6,6,0,0,0};
12         int len = arr.length;
13         char[][]kRadix = new char[len][];
14         int k = 3;
15         //轉成k進制字符數組
16         int maxLen = 0;
17         for(int i=0;i<len;i++){
18             //求每個數字的三進制字符串並翻轉,然后轉為字符數組
19             kRadix[i] = new StringBuffer(Integer.toString(arr[i],k)).reverse().toString().toCharArray();
20             if(kRadix[i].length>maxLen){
21                 maxLen = kRadix[i].length;
22             }
23         }
24         int[] resArr = new int[maxLen];
25         for(int i =0;i<len;i++){
26             //不進位加法
27             for(int j = 0;j<maxLen;j++){
28                 if(j>=kRadix[i].length){
29                     resArr[j]+=0;
30                 }else{
31                     resArr[j] +=(kRadix[i][j]-'0');
32                 }
33             }
34 
35 
36         }
37         int res = 0;
38         for(int i = 0;i<maxLen;i++){
39             res+=(resArr[i]%k)*(int)(Math.pow(k,i));//8%3=2
40         }
41         System.out.println(res);
42     }
43 }

 


免責聲明!

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



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