【題目描述】
眾所周知,小蔥同學擅長計算,尤其擅長計算乙個數是否是另外乙個數的倍數。但小蔥只擅長兩個數的情況,當有很多個數之後就會比較苦惱。現在小蔥給了你 n 個數,希望你從這 n 個數中找到三個數,使得這三個數的和是 k 的倍數,且這個和最大。資料保證一定有解。
【輸入格式】
從標準輸入讀入資料。
第一行包括 2 個正整數 n, k。
第二行 n 個正整數,代表給定的 n 個數。
【輸出格式】
輸出到標準輸出。
輸出一行乙個整數代表所求的和。
【樣例入】
4 31 2 3 4
【樣例輸出】
9【樣例解釋】
選擇2、3、4。
【資料約定】
對於 30% 的資料,n <= 100。
對於 60% 的資料,n <= 1000。
對於另外 20% 的資料,k <= 10。
對於 100% 的資料,1 <= n <= 10^5, 1 <= k <= 10^3,給定的 n 個數均不超過 10^8。
求解思路:
核心思路是要求三個變數和為k的倍數,迴圈遍歷兩個變數,第三個按照倍數等約束條件解出,然後查詢。
將輸入的n個數num分成k組,分組的依據是num%k的餘數,範圍是0~k-1。
因為k不超過1000,所以k可以考慮用陣列,每個陣列表示模k餘數相同的數。因為每個陣列的元素長度不定,所以陣列的每個元素是vector容器(int型別),將輸入的數存起來。
對vector裡每個陣列中的每個數從大到小進行排序。
第一重迴圈:i
陣列為空的不用管,continue
對於第一組,當這些陣列內資料至少有3個及以上時,把max更新為這個陣列的前三個之和。這是因為第一組是餘數為0的 一組,都是k的倍數,所以任意三個數之和都滿足是k的倍數。排序後取前三個為最大。
第二重迴圈:j
陣列為空的不用管,continue
★根據前兩重迴圈變數計算第三個變數:z = k - (i+j)%k 計算思路:既然要找三個數是k的倍數,前兩個數模k求余得i和j,i+j再模k得還差多少可以整除k。 k-(i+j)%k得z模k的值。
找到z後對z進行判斷:
1.z為負,捨去。(理論上不會,不過寫上防止出錯)
2.z,i,j三個數都相等時,這種情況在第一重迴圈中考慮過了,直接去這個陣列的前三個就可。
3.如果i和j不相等,但z和i,j中的乙個相等。即只有兩個陣列用上,乙個陣列取兩個數,另乙個陣列取乙個數。
這是如果z陣列中至少有兩個數,另乙個至少有乙個(肯定至少有乙個,因為為0的情況已經continue了)數的情況下,
max取值為i陣列的第乙個數,j陣列的第乙個數和z陣列的第二個數。(這裡比較巧妙,雖然知道了z和i,j其中乙個相等,但i,j陣列的第乙個肯定用上,z的第二個也肯定用上。雖然z和i,j乙個相等,但這裡不用區別開。將兩種情況合併。)
4.如果i和j相等,且i陣列至少有兩個數,z不和i,j相等,且z至少有乙個數的情況下,max取值為i陣列的第乙個數,j陣列的第二個數和z陣列的第乙個數。(i,j順序可變)
5.如果i,j和z三個互不相等,且各自都至少有乙個數(其實i和j肯定都至少有乙個,因為之前為空的都判斷過了,這裡主要是對z陣列的判斷)的情況下,max取值為i陣列的第乙個數,j陣列的第乙個數和z陣列的第乙個數。
#include
using
namespace std;
const
int max_k =
1e3+
100;
bool
compare
(int a,
int b)
intmain()
for(i =
0; i < k; i++
) max =0;
for(i =
0; i < k; i++)}
cout << max << endl;
return0;
}
藍橋杯倍數問題
題目描述 現在小蔥給了你 n 個數,希望你從這 n 個數中找到三個數,使得這三個數的和是 k 的倍數,且這個和最大。資料保證一定有解。1 n 10 5,1 k 10 3,給定的 n 個數均不超過 10 8。輸入格式 第一行包括 2 個正整數 n,k。第二行 n 個正整數,代表給定的 n 個數。輸出格...
藍橋杯2018初賽 倍數問題
題目描述 眾所周知,小蔥同學擅長計算,尤其擅長計算乙個數是否是另外乙個數的倍數。但小蔥只擅長兩個數的情況,當有很多個數之後就會比較苦惱。現在小蔥給了你 n 個數,希望你從這 n 個數中找到三個數 使得這三個數的和是 k 的倍數,且這個和最大。資料保證一定有解。輸入第一行包括 2 個正整數 n,k。第...
藍橋杯 倍數問題 深搜dfs
題目描述 眾所周知,小蔥同學擅長計算,尤其擅長計算乙個數是否是另外乙個數的倍數。但小蔥只擅長兩個數的情況,當有很多個數之後就會比較苦惱。現在小蔥給了你 n 個數,希望你從這 n 個數中找到三個數,使得這三個數的和是 k 的倍數,且這個和最大。資料保證一定有解。輸入格式 從標準輸入讀入資料。第一行包括...