Minimum Sum of Array(map叠代器)
You are given an array a consisting of n integers a1, ..., an. In one operation, you can choose 2 elements ai and aj in which ai is divisible by aj and transform ai to aj.
A number x is said to be divisible by a number y if x can be divided by y and the result is an exact whole number. For example, 15 is divisible by 3, because 15÷ 3 = 5 exactly, but 9 is not divisible by 2 because 9÷ 2 is 4 with 1 left over.
Your task is to find the minimum sum of the array a that can be obtained by making as many transform operations as you want. Can you?
InputThe first line contains an integer T (1 ≤ T ≤ 100) specifying the number of test cases.
The first line of each test case contains an integer n
The sum of n overall test cases does not exceed 3 × 106.
OutputFor each test case, print a single line containing the minimum sum of the array a
1Output
5
2 2 3 6 6
11
題目意思:有一個長度為n的數組,對於數組中的兩個元素x,y如果滿足y%x==0,則可以將y轉換成x,求經過多次變換後數組的前n項和最小是多少。
由於數據量較大我們選擇了map這一容器來去重。對容器中的每一個元素遍歷,開始我的打算是將每一個元素的因子都拆分,再按照從小到大的順序來一一枚舉因子(因為如果容器中有元素等於交小的因子
替換後得到的答案就是最小的),可惜超時了,於是尋求另一種方法來解決。我同學給我提供了一個新的思路,我們在求某一個數的因子的時候,為了優化算法,降低時間復雜度,會采用一種方法,比如求
12的因子的時候,我們從1到12逐個遍歷,知道2是12的因子,那麽也能得到12/2=6也是12的因子;知道了3是12的因子,那麽也同時得到了4也是12的因子。這裏也是一樣的,我們也是先依次去從小的因子
出發,找小的因子的過程中也找到了其對應的比其大的因子。如果小因子不存在,再看看對應的較大的那個因子是否存在,存在的話就保存下來。之後也是這樣增大因子,重復這個過程,要是存在對應的交大的因子就更新保存的結果,這些較小的因子都找過了依舊不滿足條件,那麽就找那個保存的那個較大的因子。
還需要註意的是mp.erase(),當在叠代器中調用這個函數的話,需要先返回上一個叠代器,不然指針會變為一個野指針(可參考鏈表理解)。
1 #include<cstdio> 2 #include<cstring> 3 #include<algorithm> 4 #include<map> 5 #define LL long long int 6 using namespace std; 7 int main() 8 { 9 int t,flag,flag1; 10 LL i,j,a,n,k; 11 LL ans,x; 12 map<LL,LL>mp; 13 map<LL,LL>::iterator it; 14 scanf("%d",&t); 15 while(t--) 16 { 17 mp.clear(); 18 scanf("%lld",&n); 19 for(i=0;i<n;i++) 20 { 21 scanf("%lld",&a); 22 mp[a]++; 23 } 24 flag=0; 25 ans=0; 26 for(it=mp.begin();it!=mp.end();it++) 27 { 28 k=it->first; 29 if(k==1)///出現1 30 { 31 flag=1; 32 break; 33 } 34 flag1=0; 35 x=0; 36 for(i=2;i*i<=k;i++) 37 { 38 if(k%i==0) 39 { 40 if(mp.count(i)) 41 { 42 mp[i]+=mp[k]; 43 it--; 44 mp.erase(k); 45 flag1=1; 46 break; 47 } 48 else if(mp.count(k/i)) 49 { 50 x=k/i; 51 } 52 } 53 } 54 if(!flag1) 55 { 56 if(x) 57 { 58 mp[x]+=mp[k]; 59 it--; 60 mp.erase(k); 61 } 62 } 63 } 64 if(flag) 65 { 66 printf("%lld\n",n); 67 } 68 else 69 { 70 for(it=mp.begin();it!=mp.end();it++) 71 { 72 ans+=it->second*it->first; 73 } 74 printf("%lld\n",ans); 75 } 76 } 77 return 0; 78 }
Minimum Sum of Array(map叠代器)