2018 第九屆藍橋杯大賽個人賽省賽 Java A 題解
試題A
標題:倍數問題
【題目描述】
眾所周知,小蔥同學擅長計算,尤其擅長計算一個數是否是另外一個數的倍數,但小蔥只擅長兩個數的情況,當有很多個數之后就會比較苦惱,現在小蔥給了你 n 個數,希望你從這 n 個數中找到三個數,使得這三個數的和是 K 的倍數,且這個和最大,資料保證一定有解,
代碼
private static void questionA() {
int n = 1;
int m = 1;
for (int i = 2; i <= 20; i++) {
n = (n << 1) + 1;
m <<= 1;
}
System.out.println(n + "/" + m);
}
答案
1048575/524288
試題B
標題:星期一
整個20世紀(1901年1月1日至2000年12月31日之間),一共有多少個星期一?
(不要告訴我你不知道今天是星期幾)
題解
? 先計算期間總共有多少天
? 總天數中有幾個整星期
? 最后查看余下的天數中是否有經過周一
代碼
public static void questionB() {
int day = 0;
for (int i = 1901; i <= 2000; i++) {
day += is(i) ? 366 : 365;
}
Calendar cal = Calendar.getInstance();
cal.set(1901, 0, 1);
int week = cal.get(Calendar.DAY_OF_WEEK);
int ans = day / 7;
day %= 7;
ans += (day + week - 1) % 7 >= Calendar.MONDAY ? 1 : 0;
System.out.println(ans);
}
public static boolean is(int x) {
return (x % 4 == 0 && x % 100 != 0) || (x % 400 == 0);
}
答案
5217
試題C
標題:復數冪
設i為虛數單位,對于任意正整數n,(2+3i)^n 的實部和虛部都是整數,
求 (2+3i)^123456 等于多少? 即(2+3i)的123456次冪,這個數字很大,要求精確表示,
題解
? 對于復數\(z_1=x_1+i·y_1\) 和 \(z_2=x_2+i·y_2\)
? 有 \(z_1·z_2 = (x_1·x_2 - y_1·y_2) + i · (x_2·y_1 + x_1·y_2)\)
? 注意結果非常大,應該將結果輸出到檔案中,
代碼
public static void questionC() throws IOException {
BigInteger x = new BigInteger("2");
BigInteger y = new BigInteger("3");
BigInteger rel = new BigInteger("2");
BigInteger imz = new BigInteger("3");
for (int i = 2; i <= 123456; i++) {
BigInteger temp = x.multiply(rel).subtract(y.multiply(imz));
y = x.multiply(imz).add(y.multiply(rel));
x = temp;
}
FileWriter fw = new FileWriter("questionC.txt");
fw.write(x.toString() + y.toString() + "i");
fw.close();
}
答案
可惜這里寫不下
試題D
標題:方格計數
如圖所示,在二維平面上有無數個1x1的小方格,
我們以某個小方格的一個頂點為圓心畫一個半徑為 50000 的圓,
你能計算出這個圓里有多少個完整的小方格嗎?
題解
? 已知平面上任意一頂點 \((i, j)\) 到原點距離的平方為 \(d^2=(i · i + j · j)^2\)
? 若距離 d 小于等于圓半徑 r,則頂點在圓內
? 故可以窮舉第一象限
代碼
public static void questionB() {
int r = 1000;
int ans = 0;
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= r; j++) {
if (i * i + j * j <= r * r)
ans++;
}
}
System.out.println(ans << 2);
}
試題E
答案
n / 3
試題F
標題:航班時間
【問題背景】
小h前往美國參加了藍橋杯國際賽,小h的女朋友發現小h上午十點出發,上午十二點到達美國,于是感嘆到“現在飛機飛得真快,兩小時就能到美國了”,
小h對超音速飛行感到十分恐懼,仔細觀察后發現飛機的起降時間都是當地時間,由于北京和美國東部有12小時時差,故飛機總共需要14小時的飛行時間,
不久后小h的女朋友去中東交換,小h并不知道中東與北京的時差,但是小h得到了女朋友來回航班的起降時間,小h想知道女朋友的航班飛行時間是多少,
題解
? 設時差為\(\Delta t\) ,飛行時間為 \(f_t\)
? 對于啟程有 \(t_2 = t_1 + f_t + \Delta t\)
? 對于返程有 \(t_4 = t_3 + f_t - \Delta t\)
? 則 \(f_t = ((t_2 + t_4) - (t_1 + t_3)) / 2\)
? 我們可以將時間轉換成秒,這樣可以方便時間的加減運算,
代碼
public static void questionF() {
Scanner sc = new Scanner(System.in);
int T = sc.nextInt();
sc.nextLine();
while (T-- > 0) {
String[] go = sc.nextLine().split(" ");
String[] back = sc.nextLine().split(" ");
int t1 = toSecond(go[0]);
int t2 = toSecond(go[1]);
if (go.length > 2)
t2 += (go[2].charAt(2) - '0') * 24 * 3600;
int t3 = toSecond(back[0]);
int t4 = toSecond(back[1]);
if (back.length > 2)
t4 += (back[2].charAt(2) - '0') * 24 * 3600;
int ft = ((t2 + t4) - (t1 +t3)) >> 1;
System.out.println(toTime(ft));
}
}
public static int toSecond(String time) {
String[] ts = time.split(":");
int h = Integer.parseInt(ts[0]);
int m = Integer.parseInt(ts[1]);
int s = Integer.parseInt(ts[2]);
return h * 3600 + m * 60 + s;
}
public static String toTime(int second) {
String[] ts = new String[3];
ts[0] = String.valueOf(second / 3600);
second %= 3600;
ts[1] = String.valueOf(second / 60);
second %= 60;
ts[2] = String.valueOf(second);
StringBuilder ans = new StringBuilder();
for (int i = 0; i < 3; i++) {
if (ts[i].length() < 2)
ans.append("0");
ans.append(ts[i]);
if (i == 2) break;
ans.append(":");
}
return ans.toString();
}
試題G
標題:三體攻擊
【題目描述】
三體人將對地球發起攻擊,為了抵御攻擊,地球人派出了 A?×?B?×?C 艘戰艦,在太空中排成一個 A 層 B 行 C 列的立方體,其中,第 i 層第 j 行第 k 列的戰艦(記為戰艦 (i,?j,?k))的生命值為 d(i,?j,?k),
三體人將會對地球發起 m 輪“立方體攻擊”,每次攻擊會對一個小立方體中的所有戰艦都造成相同的傷害,具體地,第 t 輪攻擊用 7 個引數 lat,?rat,?lbt,?rbt,?lct,?rct,?ht 描述;
所有滿足 i?∈?[lat,?rat],j?∈?[lbt,?rbt],k?∈?[lct,?rct] 的戰艦 (i,?j,?k) 會受到 ht 的傷害,如果一個戰艦累計受到的總傷害超過其防御力,那么這個戰艦會爆炸,
地球指揮官希望你能告訴他,第一艘爆炸的戰艦是在哪一輪攻擊后爆炸的,
題解
? 使用三維陣列模擬戰艦
代碼
public static void questionG() {
Scanner sc = new Scanner(System.in);
int A = sc.nextInt();
int B = sc.nextInt();
int C = sc.nextInt();
int m = sc.nextInt();
int[][][] d = new int[A + 1][B + 1][C + 1];
for (int i = 1; i <= A; i++) {
for (int j = 1; j <= B; j++) {
for (int k = 1; k <= C; k++) {
d[i][j][k] = sc.nextInt();
}
}
}
for (int l = 1; l <= m; l++) {
int lat = sc.nextInt();
int rat = sc.nextInt();
int lbt = sc.nextInt();
int rbt = sc.nextInt();
int lct = sc.nextInt();
int rct = sc.nextInt();
int ht = sc.nextInt();
for (int i = lat; i <= rat; i++) {
for (int j = lbt; j<= rbt; j++) {
for (int k = lct; k <= rct; k++) {
d[i][j][k] -= ht;
if (d[i][j][k] < 0) {
System.out.println(l);
return;
}
}
}
}
}
}
試題H
標題:全球變暖
你有一張某海域NxN像素的照片,"."表示海洋、"#"表示陸地,如下所示:
.......
.##....
.##....
....##.
..####.
...###.
.......
其中"上下左右"四個方向上連在一起的一片陸地組成一座島嶼,例如上圖就有2座島嶼,
由于全球變暖導致了海面上升,科學家預測未來幾十年,島嶼邊緣一個像素的范圍會被海水淹沒,具體來說如果一塊陸地像素與海洋相鄰(上下左右四個相鄰像素中有海洋),它就會被淹沒,
題解
? 將與海洋相鄰的陸地像素做特殊標記!
? 再將未淹沒的陸地與相鄰未淹沒的區域連通
? 最后統計并查集中島嶼的數量
代碼
private static int[] parent;
private static int find(int x) {
if (parent[x] < 0)
parent[x] = x;
else if (parent[x] != x)
parent[x] = find(parent[x]);
return parent[x];
}
public static void union(int x, int y) {
int rootX = find(x);
int rootY = find(y);
if (rootX == rootY)
return;
parent[rootX] = rootY;
}
public static void questionI() {
Scanner sc = new Scanner(System.in);
int N = sc.nextInt();
char[][] board = new char[N][N];
for (int i = 0; i < N; i++) {
String line = sc.next();
for (int j = 0; j < N; j++) {
board[i][j] = line.charAt(j);
}
}
parent = new int[N * N];
Arrays.fill(parent, -1);
int[][] delta = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}};
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (board[i][j] != '#')
continue;
for (int k = 0; k < 4; k++) {
int x = i + delta[k][0];
int y = j + delta[k][1];
if (x >= 0 && x < N && y >= 0 && y < N && board[x][y] == '.') {
board[i][j] = '!';
break;
}
}
}
}
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if(board[i][j] != '#')
continue;
union(i * N + j , i * N + j);
for (int k = 0; k < 4; k++) {
int x = i + delta[k][0];
int y = j + delta[k][1];
if (x >= 0 && x < N && y >= 0 && y < N && board[x][y] == '#') {
union(i * N + j, x * N + j);
}
}
}
}
int ans = 0;
for (int i = 0; i < parent.length; i++) {
if (i == parent[i])
ans++;
}
System.out.println(ans);
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/258003.html
標籤:其他
上一篇:非遞減數列(貪心)
