2018-7-9 ACM 刷題日記
阿新 • • 發佈:2018-12-31
<Codeforces 977D>
題意:
給定一串序列,問能否讓序列形成一個順序,使得序列某一項是由它前一項乘2或者前一項整除3得來的,列印該順序。
思路:
一開始我的思路是這樣的,就是先找只能被3整除和只能被2整除的(即不能同時被3和2整除,即不能被6整除的數),然後:
先將只能被3整除的降序排,因為下一項是由當前項除3得到的,顯然遞減,故降序;
再將只能被2整除的升序排,因為下一項是由當前項乘2得到的,顯然遞增,故升序。
接下來就是將被6整除的數夾在只能被3整除和只能被2整除的數中間了,然後到這裡就進行不下去了。
所以,換了種思路,首先想一下這個序列要想滿足題意顯然是有一個順序的,這個順序的規律是關鍵所在,仔細想下,由於每個數都只能進行除3或者乘2的操作,我當時的思路,有一點是對的,那就是,只能被2整除的數顯然是放在最後且升序排列的 ,只能被2整除的數,因子3個數是0。那麼,這個只能被2整除的升序序列的第一項,即他的最小項,肯定是由它前一項除3過來的,這就意味著,他的前一項至少有一個因子3。到這裡思路就越來越明朗了,再想一下,這個序列,每個數,3因子的個數顯然是逐漸遞減的(非嚴格遞減),因為因子3只能被除,所以只需要按因子3的個數進行降序排序即可,如果碰到因子3的個數相等的某幾個數,那就意味著不能通過除3這種操作到達,那就只能乘2,所以遞增即可,即,將因子3個數相等的子序列升序排即可。
本人AC程式碼:
#include<cstdio>#include<cstring>#include<cmath> #include<cctype>#include<cstdlib>#include<ctime>#include<set>#include<map>#include<queue>#include<vector>#include<iostream>#include<algorithm>usingnamespace std;typedefunsignedlonglong ull;constint maxx =107;constintInf=1e9+7;set<int> sst;vector <int> vect;map<ull,bool> vis;typedef pair <int,int> pr;priority_queue<pr> qua;int n;
ull a[maxx];intCnt(ull x){ // 列舉因子3的個數int cnt =0;while(!(x %3)){
cnt++;
x /=3;}return cnt;}boolCmp(ull x, ull y){ // 按因子3的個數降序排列,個數相等時直接普通升序排列即可if(Cnt(x)==Cnt(y))return x < y;returnCnt(x)>Cnt(y);}int main(){
cin >> n;for(int i =1; i <= n; i++) cin >> a[i];
sort(a +1, a + n +1,Cmp);for(int i =1; i <= n; i++){if(i != n) cout << a[i]<<" ";else cout << a[i]<< endl;}}