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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

CodeForces - 1267K Key Storage(组合数学)

發(fā)布時(shí)間:2024/4/11 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CodeForces - 1267K Key Storage(组合数学) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目鏈接:點(diǎn)擊查看

題目大意:給出一個(gè)正整數(shù)num,現(xiàn)在將其進(jìn)行除以2、除以3、除以4....的操作,直到num變?yōu)?為止,期間記錄每一次運(yùn)算的余數(shù),將其排序后得到一個(gè)集合,現(xiàn)在問(wèn)有多少不同的數(shù)字經(jīng)相同處理后的集合與num的集合相等

題目分析:如果想讓余數(shù)組成的集合相等,需要排列組合計(jì)算個(gè)數(shù),比如正常的全排列,若是有n個(gè)數(shù),那么對(duì)于第一個(gè)位置,可以有n種選擇,對(duì)于第2個(gè)數(shù),可以有n-1種選擇,依次類推得到的是全排列的公式n!,但是考慮到這個(gè)題目對(duì)于每個(gè)位置可供選擇的余數(shù)都是有限制的,所以不能貿(mào)然直接用全排列去計(jì)算,不過(guò)我們可以借助全排列的思想去進(jìn)行實(shí)現(xiàn),因?yàn)樵酵蟮南拗圃叫?#xff0c;所以我們可以從第一位進(jìn)行選擇,因?yàn)閷?duì)于第i位的余數(shù),可以選擇的范圍是0~i(第i位的余數(shù)是被除數(shù)除以(i+1)得到的),所以先將前面的方案數(shù)確定,利用全排列的思想依次確定后續(xù)的方案數(shù),最后記得去重,因?yàn)橛兄貜?fù)元素,每種相同的元素個(gè)數(shù)為cnt,則會(huì)重復(fù)計(jì)算cnt!次,因?yàn)檫@cnt個(gè)相同元素內(nèi)部全排列后的結(jié)果都是一樣的,最后這個(gè)題目還有一個(gè)細(xì)節(jié),就是第一位上肯定不能為0,因?yàn)?不可能作為被除數(shù)出現(xiàn)在這個(gè)題目中,最后一次的除法運(yùn)算肯定是商為0,余數(shù)為其本身才能達(dá)到終止循環(huán),這樣一來(lái)答案需要減去最后一位為0的方案數(shù),最后ans-1就是答案了,減去當(dāng)前這個(gè)數(shù)的本身

2020.9.3更新:

昨天訓(xùn)練的時(shí)候碰到的原題,最后那個(gè)細(xì)節(jié),也就是最后一個(gè)位置忘記不能是零了,怎么都跑不出樣例,就非常自閉了,還有去年寫的代碼,也是仿照別人的代碼寫的,就是非常的丑,關(guān)于階乘和統(tǒng)計(jì)多少個(gè)小于當(dāng)前位置的數(shù),用前綴和不香嘛,后面附上重構(gòu)后的代碼

代碼:

#include<iostream> #include<cstdlib> #include<string> #include<cstring> #include<cstdio> #include<algorithm> #include<climits> #include<cmath> #include<cctype> #include<stack> #include<queue> #include<list> #include<vector> #include<set> #include<map> #include<sstream> using namespace std;typedef long long LL;const int inf=0x3f3f3f3f;const int N=1e3+100;vector<int>v;void init(LL x) {v.clear();for(int i=2;x;i++){v.push_back(x%i);x/=i;}sort(v.begin(),v.end()); }LL solve() {LL ans=1;for(int i=0;i<v.size();i++){int cnt=0;for(int j=0;j<v.size();j++){if(v[j]<i+2)cnt++;}ans*=cnt-i;}LL fac=1;for(int i=0;i<v.size()-1;i++){if(v[i]==v[i+1])ans/=++fac;elsefac=1;}return ans; }int main() { // freopen("input.txt","r",stdin); // ios::sync_with_stdio(false);int w;cin>>w;while(w--){LL num;scanf("%lld",&num);init(num);LL ans=solve();if(v[0]==0){v.erase(v.begin());ans-=solve();}printf("%lld\n",ans-1);}return 0; }

更新:

#include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<unordered_map> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=1e5+100;const int M=20;vector<int>node;LL sum[M],fac[M],cnt[M];void init(LL n) {node.clear();for(int i=2;n;i++){node.push_back(n%i);n/=i;}sort(node.begin(),node.end()); }LL solve() {LL ans=1;memset(sum,0,sizeof(sum));memset(cnt,0,sizeof(cnt));for(int num:node){sum[num]++;cnt[num]++;}for(int i=1;i<M;i++)sum[i]+=sum[i-1];for(int i=1;i<=node.size();i++)ans*=(sum[i]-(i-1));for(int i=0;i<M;i++)ans/=fac[cnt[i]];return ans; }int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);fac[0]=1;for(int i=1;i<M;i++)fac[i]=fac[i-1]*i;int w;cin>>w;while(w--){LL n;scanf("%lld",&n);init(n);LL ans=solve();if(node.front()==0){node.erase(node.begin());ans-=solve();}printf("%lld\n",ans-1);}return 0; }

?

總結(jié)

以上是生活随笔為你收集整理的CodeForces - 1267K Key Storage(组合数学)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。