Good Bye 2018 D. New Year and the Permutation Concatenation
阿新 • • 發佈:2018-12-31
https://www.cnblogs.com/violet-acmer/p/10201535.html
題意:
求 n 的所有全排列組成的序列中連續的 n 個數加和為 n*(n+1)/2 的區間個數。
題解:
n 最大為1e6,而n的全排列個數為 n! ,一共有 n*n!個數,存都存不下啊......
然後,第一反應就是,這題是找規律的。
一言不合就打表
==========
i=1
1
==========
i=2
2
==========
i=3
9
==========
i=4
56
==========
i=5
395
==========
i=6
3084
==========
i=7
26621
起初,想到了數 n 有 n! 個全排列,那麼,這 n! 個全排列肯定滿足條件,那麼剩下的情況呢?
i=3 : 9=3!+3...........................3=3*1=3*(2-1);
i=4 : 56=4!+32.......................32=4*8=4*(9-1);
i=5 : 395=5!+275 ..................275=5*55=5*(56-1);
仔細觀察一下括號中的2,9,56,相信這個規律很好找吧..........
AC程式碼:
1 #include<iostream> 2View Code#include<cstdio> 3 #include<algorithm> 4 #include<cstring> 5 using namespace std; 6 #define ll __int64 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 const ll MOD=998244353; 9 const int maxn=1e6+10; 10 11 int n; 12 ll a[maxn]; 13 14 int main() 15 { 16 cin>>n; 17 a[1]=1; 18 ll fact=1;//階乘 19 for(int i=2;i <= n;++i) 20 { 21 fact=fact*i%MOD; 22 a[i]=fact+i*(a[i-1]-1); 23 a[i] %= MOD; 24 } 25 cout<<a[n]<<endl; 26 }
打表找規律程式碼:
1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 using namespace std; 5 const int maxn=1e6; 6 7 int p[maxn]; 8 int b[maxn]; 9 10 int main() 11 { 12 for(int i=1;i <= 6;++i) 13 { 14 for(int j=0;j < i;++j) 15 b[j]=j+1; 16 17 int index=1; 18 do 19 { 20 for(int j=0;j < i;++j) 21 p[index++]=b[j]; 22 }while(next_permutation(b,b+i)); 23 int res=0; 24 for(int j=1;j+i <= index;++j) 25 { 26 int sum=0; 27 for(int k=j;k < j+i;++k) 28 sum += p[k]; 29 30 if(sum == i*(i+1)/2) 31 res++; 32 } 33 printf("==========\ni=%d\n",i); 34 printf("%d\n",res); 35 } 36 }View Code
用到了一個騷操作:next_permutation();
爽歪歪,哈哈哈