日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

蓝桥杯第八届省赛JAVA真题----k倍区间

發布時間:2025/3/15 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 蓝桥杯第八届省赛JAVA真题----k倍区间 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

標題: k倍區間

給定一個長度為N的數列,A1, A2, ... AN,如果其中一段連續的子序列Ai, Ai+1, ... Aj(i <= j)之和是K的倍數,我們就稱這個區間[i, j]是K倍區間。??

你能求出數列中總共有多少個K倍區間嗎???

輸入
-----
第一行包含兩個整數N和K。(1 <= N, K <= 100000)??
以下N行每行包含一個整數Ai。(1 <= Ai <= 100000)??

輸出
-----
輸出一個整數,代表K倍區間的數目。??

例如,
輸入:
5 2
1??
2??
3??
4??

5??

程序應該輸出:
6

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

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

所有代碼放在同一個源文件中,調試通過后,拷貝提交該源碼。
不要使用package語句。不要使用jdk1.7及以上版本的特性。

主類的名字必須是:Main,否則按無效代碼處理。

思路:題目中的例子6種情況為:2 4 123 345 1234 2345 。這不是一道難度很大的題,至少在理解上是的,但是一般思路做出來的方法肯定是得不了滿分的,這可能也是藍橋杯的另一種“套路”吧,將題目的理解變簡單,但是要求變困難。這里就更能體現出算法的重要性。

一開始上來就這直接暴力求了,結果做完時間復雜度為O(n^3),嚴重超時,甚至還有一個非常不必要的嵌套。

import java.util.Scanner; public class Main {static int n = 0;static int k = 0;static int[] a;static int cnt = 0;public static void main(String[] args) {Scanner in = new Scanner(System.in);n = in.nextInt();k = in.nextInt();a = new int[n+1];for (int i = 0; i < n; i++) {a[i] = in.nextInt();}for (int i = 0; i < n; i++) {for (int j = i; j < n; j++) {if (sum(i, j)% k == 0) {cnt++;}}}System.out.println(cnt);}private static int sum(int i, int j) {// TODO Auto-generated method stubint s = 0;for (int k = i; k <= j; k++) {s += a[k];}return s;} }

接下來,消除嵌套之后,時間復雜度降到了O(n^2),但實際上這個題目必須達到線性O(n)才能得到滿分。

import java.util.Scanner; public class Main {static int n = 0;static int k = 0;static int[] a;static int cnt = 0;static int sum;public static void main(String[] args) {Scanner in = new Scanner(System.in);n = in.nextInt();k = in.nextInt();a = new int[n+1];for (int i = 0; i < n; i++) {a[i] = in.nextInt();}for (int i = 0; i < n; i++) {sum = 0;for (int j = i; j < n; j++) {sum += a[k];if (sum % k == 0) {cnt++;}}}System.out.println(cnt);} }

參考了大神的代碼2017第八屆藍橋杯C/C++ B組省賽題解

下面這個代碼非常巧妙,將前綴和保存到數組中,減少每次不必要的嵌套計算,而同時%k會產生兩種結果,0或者小于k,這相當于直接記錄了符合(%k = 0)與不符合(%k < k)兩種情況。根據(sum[r] - sum[l-1]) % k == 0 就可以判斷一個區間[l, r]是符合約束區間。但是這樣會使用雙重循環,時間復雜度為O(n^2),這樣并沒有完全把這種算法的好處利用到,而且我們的目的是計算個數,而非要輸出所有的k倍區間。

根據上面的式子我們可以看出只要區間兩端點的前綴和%k相等,那么這段區間就符合約束,所以我們只需每次使sum加上與當前位置前綴和%k相等的數量(即bk[a[i]]++)就行。

(注意最后的結果還要加上前綴和%k=0的值,這是它自身到1的區間,也符合約束。)

import java.util.Scanner; public class Main {static int n = 0;static int k = 0;static int sum;static int[] a;static int[] bk;static int cnt = 0;public static void main(String[] args) {Scanner in = new Scanner(System.in);n = in.nextInt();k = in.nextInt();a = new int[n+1];bk = new int[n+1];for (int i = 0; i < n; i++) {a[i] = in.nextInt();}a[0] %= k;for (int i = 1; i < n; i++) {a[i] = (a[i] + a[i-1]) % k;}for (int i = 0; i < n; i++) {sum += (bk[a[i]]++);}System.out.println(sum + " "+ bk[0]);} }

?

?

?

總結

以上是生活随笔為你收集整理的蓝桥杯第八届省赛JAVA真题----k倍区间的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。