第十二届蓝桥杯A组省赛填空题Java思路及代码合集(相乘直线货物摆放路径回路计数)
文章目錄
- 試題 A: 相乘
- 試題 B: 直線
- 試題 C: 貨物擺放
- 試題 D: 路徑
- 試題 E: 回路計數
試題 A: 相乘
本題總分:5 分
【問題描述】
小藍發現,他將 1 至 1000000007 之間的不同的數與 2021 相乘后再求除以1000000007 的余數,會得到不同的數。小藍想知道,能不能在 1 至 1000000007 之間找到一個數,與 2021 相乘后再除以 1000000007 后的余數為 999999999。如果存在,請在答案中提交這個數;如果不存在,請在答案中提交 0。
【答案提交】
這是一道結果填空的題,你只需要算出結果后提交即可。本題的結果為一個整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。
【思路】
直接暴力,不過記得用long數據類型。
【Java代碼】
public class Xiang {public static void main(String[] args) {long res = 0;for(long i = 1; i <= 1000000007L; i++) {if((i * 2021) % 1000000007L == 999999999L) {res = i;break;} }System.out.println(res);} }【結果】
17812964
試題 B: 直線
本題總分:5 分
【問題描述】
在平面直角坐標系中,兩點可以確定一條直線。如果有多點在一條直線上,那么這些點中任意兩點確定的直線是同一條。給定平面上 2 × 3 個整點 {(x, y)|0 ≤ x < 2, 0 ≤ y < 3, x ∈ Z, y ∈ Z},即橫坐標是 0 到 1 (包含 0 和 1) 之間的整數、縱坐標是 0 到 2 (包含 0 和 2) 之間的整數的點。這些點一共確定了 11 條不同的直線。給定平面上 20 × 21 個整點 {(x, y)|0 ≤ x < 20, 0 ≤ y < 21, x ∈ Z, y ∈ Z},即橫坐標是 0 到 19 (包含 0 和 19) 之間的整數、縱坐標是 0 到 20 (包含 0 和 20) 之間的整數的點。請問這些點一共確定了多少條不同的直線。
【答案提交】
這是一道結果填空的題,你只需要算出結果后提交即可。本題的結果為一個整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。
【思路】
①每個點坐標(x,y),即有兩個數據組成,可以使用String類型“x,y”形式存儲。使用時split以“,”分開并且使用Integer的ParseInt。
②兩點確定一直線使用兩點式(y-y1)/(y2-y1)=(x-x1)/(x2-x1)表示直線,轉換成標準式(y1-y2)x+(x2-x1)y-y1(x2-x1)+x1(y2-y1)=0。
③對系數和常數進行約分,即求三者最大公因數。
④取唯一,即對于求得結構相同的只算一次,可以考慮使用HashSet存儲。
【Java代碼】
import java.util.ArrayList; import java.util.HashSet;public class test {public static void main(String[] args) {//生成存儲點ArrayList<String> ps = new ArrayList<>();for (int i = 0; i < 20; i++) {for (int j = 0; j < 21; j++) {//以"x,y"形式存儲ps.add(i + "," + j);}}//取點求直線HashSet<String> line = new HashSet<>();//第一層循環取第一個點for (int i = 0; i < ps.size(); i++) {String p1 = ps.get(i);int x1 = Integer.parseInt(p1.split(",")[0]);int y1 = Integer.parseInt(p1.split(",")[1]);//第二層循環取第二個點for (int j = i+1; j < ps.size(); j++) {String p2 = ps.get(j);int x2 = Integer.parseInt(p2.split(",")[0]);int y2 = Integer.parseInt(p2.split(",")[1]);//根據(y1-y2)x+(x2-x1)y-y1(x2-x1)+x1(y2-y1)=0求系數及常數int a = y1 - y2;int b = x2 - x1;int c = x1*(y2-y1)-y1*(x2-x1);//求最大公因數約分int m = gcd(gcd(a, b), c);a /= m; b/= m; c/= m;line.add(a + "," + b + "," + c);}}System.out.println(line.size());}//求最大公因數public static int gcd(int a, int b){return b == 0 ? a : gcd(b, a%b);} }【結果】
40257
試題 C: 貨物擺放
本題總分:10 分
【問題描述】
小藍有一個超大的倉庫,可以擺放很多貨物?,F在,小藍有 n 箱貨物要擺放在倉庫,每箱貨物都是規則的正方體。小藍規定了長、寬、高三個互相垂直的方向,每箱貨物的邊都必須嚴格平行于長、寬、高。小藍希望所有的貨物最終擺成一個大的立方體。即在長、寬、高的方向上分別堆 L、W、H 的貨物,滿足 n = L × W × H。
給定 n,請問有多少種堆放貨物的方案滿足要求。
例如,當 n = 4 時,有以下 6 種方案:1×1×4、1×2×2、1×4×1、2×1×2、 2 × 2 × 1、4 × 1 × 1。
請問,當 n = 2021041820210418 (注意有 16 位數字)時,總共有多少種方案?
提示:建議使用計算機編程解決問題。
【答案提交】
這是一道結果填空的題,你只需要算出結果后提交即可。本題的結果為一個整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。
【思路】
①由于n值過大,直接暴力破解會超時。
②因此考慮到縮小數據,由題意可知L、W、H可能取值都是n的因子,因此只要找到n的全部因子,然后再循環破解就可以了,找因子時開方也極大縮小了數據。
【Java代碼】
import java.util.ArrayList;public class test {public static void main(String[] args) {long n = 2021041820210418l;//找出n的所有因子并保存ArrayList<Long> list = new ArrayList<>();for (long i = 1l; i < Math.sqrt(n)+1; i++) {if (n % i == 0){list.add(i);if (i * i != n){list.add(n/i);}}}//所有因子進行匹配int count = 0;for (int i = 0; i < list.size(); i++) {for (int j = 0; j < list.size(); j++) {for (int k = 0; k < list.size(); k++) {if (list.get(i)*list.get(j)*list.get(k) == n){count++;break;}}}}System.out.println(count);} }【結果】
2430
試題 D: 路徑
【問題描述】
小藍學習了最短路徑之后特別高興,他定義了一個特別的圖,希望找到圖 中的最短路徑。
小藍的圖由 2021 個結點組成,依次編號 1 至 2021。
對于兩個不同的結點 a, b,如果 a 和 b 的差的絕對值大于 21,則兩個結點 之間沒有邊相連;如果 a 和 b 的差的絕對值小于等于 21,則兩個點之間有一條 長度為 a 和 b 的最小公倍數的無向邊相連。
例如:結點 1 和結點 23 之間沒有邊相連;結點 3 和結點 24 之間有一條無 向邊,長度為 24;結點 15 和結點 25 之間有一條無向邊,長度為 75。
請計算,結點 1 和結點 2021 之間的最短路徑長度是多少。
【答案提交】
這是一道結果填空的題,你只需要算出結果后提交即可。本題的結果為一個整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。
【思路】
帶權最短路徑,可以使用Floyd算法實現。(關于Floyd算法可以自行搜索)
【Java代碼】
public class Floyd {//求a和b的最小公約數static int gcd(int a,int b){return b == 0 ? a : gcd(b,a%b);}//求a和b的最小公倍數static int lcm(int a,int b){return a * b / gcd(a,b);}public static void main(String[] args) {//初始化方陣int[][] floyd = new int[2021][2021];for (int i = 0; i < 2021; i++) {for (int j = i + 1; j < i + 22 && j < 2021; j++) {floyd[i][j] = floyd[j][i] = lcm(i+1, j+1);}}//Floyd算法for (int k = 0; k < floyd.length; k++) {for (int i = 0; i < floyd.length; i++) {for (int j = 0; j < floyd.length; j++) {if (floyd[i][k] != 0 && floyd[k][j] != 00 && (floyd[i][j] == 0 || floyd[i][j] > floyd[i][k] + floyd[k][j])) {floyd[i][j] = floyd[i][k] + floyd[k][j];}}}}//輸出第一個點到第2021個點的距離System.out.println(floyd[0][2020]);} }【結果】
10266837
試題 E: 回路計數
本題總分:15 分
【問題描述】
藍橋學院由 21 棟教學樓組成,教學樓編號 1 到 21。對于兩棟教學樓 a 和 b,當 a 和 b 互質時,a 和 b 之間有一條走廊直接相連,兩個方向皆可通行,否則沒有直接連接的走廊。
小藍現在在第一棟教學樓,他想要訪問每棟教學樓正好一次,最終回到第一棟教學樓(即走一條哈密爾頓回路),請問他有多少種不同的訪問方案?兩個訪問方案不同是指存在某個 i,小藍在兩個訪問方法中訪問完教學樓 i 后訪問了不同的教學樓。
提示:建議使用計算機編程解決問題。
【答案提交】
這是一道結果填空的題,你只需要算出結果后提交即可。本題的結果為一個整數,在提交答案時只填寫這個整數,填寫多余的內容將無法得分。
【思路】
深度優先搜索+Map剪枝
【Java代碼】
import java.util.ArrayList; import java.util.HashMap; import java.util.Map;public class DPMAP {//求a和b的最小公約數static int gcd(int a,int b){return b == 0 ? a : gcd(b,a%b);}static ArrayList<Integer>[] list = new ArrayList[22]; //鄰接表存儲每個教學樓及其可以到達的教學樓static Map<String, Long> set = new HashMap<String, Long>(); //存儲狀態及其路線條數public static void main(String[] args) {//初始化鄰接表for (int i = 1; i < list.length; i++)list[i] = new ArrayList<Integer>();for (int i = 1; i < 22; i++)for (int j = i + 1; j < 22; j++)if (gcd(i, j) == 1) {list[i].add(j);list[j].add(i);}System.out.println(dfs(21, 1, 0));}//深度優先搜索public static long dfs(int total, int begin, int state) {if (total == 0) return 1; //返回第一棟教學樓了long res = 0;for (int p : list[begin]) {if ((state & (1 << p)) != (1 << p)) {long r = 0;if (set.containsKey(p + "-" + state)) { //剪枝r = set.get(p + "-" + state);} else {if (p != 1 || p == 1 && total == 1) {r = dfs(total-1, p, state | (1 << p));}set.put(p + "-" + state, r);}res += r;}}return res;} }【結果】
881012367360
總結
以上是生活随笔為你收集整理的第十二届蓝桥杯A组省赛填空题Java思路及代码合集(相乘直线货物摆放路径回路计数)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 安卓屏幕锁忘记了怎么解锁(安卓屏幕锁)
- 下一篇: 第十二届蓝桥杯A组省赛试题 I: 双向排