一直不大喜欢写题解 尤其做的很纠结的题目 终于纠结完了 就想代码一贴完事。缺点一:理解不透彻;二:很容易忘;三:不利于以后回顾复习;四:写代码容易乱;
以这个专题为开始吧 把一些题目总结一下 解释一下 同一类型的放在一块 。
hdu1465 不容易系列之一 (错排公式)
虽说大家知道 还是把这个小小说一下
来自百度百科
1 #include <iostream> 2 #include<cstdio> 3 #include<stdlib.h> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<vector> 8 #include<queue> 9 #include<stack> 10 #include<set> 11 using namespace std; 12 #define LL long long 13 LL f[22]; 14 int main() 15 { 16 int i,n; 17 f[1] = 0; 18 f[2] = 1; 19 while(cin>>n) 20 { 21 for(i = 3; i <= n ; i++) 22 f[i] = (i-1)*(f[i-1]+f[i-2]); 23 cout<<f[n]<<endl; 24 } 25 return 0; 26 }
poj1850 Code
以前做过 没印象了。。
仔细想一下 也是很简单的 一个字母的所有排列就是C(n,1),二个字母C(n,2),三个字母C(n,3)........依次
具体的就类似于逐位了 注意下细节就OK了
1 #include <iostream> 2 #include<cstdio> 3 #include<stdlib.h> 4 #include<cstring> 5 #include<algorithm> 6 #include<cmath> 7 #include<vector> 8 #include<queue> 9 #include<stack> 10 #include<set> 11 using namespace std; 12 #define LL long long 13 char s[12]; 14 LL c[30][15]; 15 void init() 16 { 17 int i,j; 18 for(i = 0 ;i <= 26 ;i++) 19 c[i][0] = 1; 20 for(i = 1 ; i <= 26 ;i++) 21 for(j = 1 ; j <= 10 ; j++) 22 c[i][j] = c[i-1][j-1]+c[i-1][j]; 23 } 24 int main() 25 { 26 int i,j,k; 27 init(); 28 while(cin>>s) 29 { 30 k = strlen(s); 31 if(k>1) 32 { 33 for(i = 0 ; i < k-1 ; i++) 34 if(s[i+1]<s[i]) break; 35 if(i!=k-1) {puts("0");continue;} 36 } 37 LL ans=0; 38 for(i = 1 ; i < k ;i++) 39 ans+=c[26][i]; 40 int t; 41 for(i = 0; i < k ;i++) 42 { 43 if(i!=0) 44 t = 'z'-s[i-1]-1; 45 else 46 t = 25; 47 //cout<<'z'-s[i]+1<<endl; 48 for(j = max(('z'-s[i]+1),k-i-1) ; j <= t ; j++) 49 { 50 //cout<<j<<endl; 51 ans+=c[j][k-i-1]; 52 } 53 } 54 ans++; 55 cout<<ans<<endl; 56 } 57 return 0; 58 }
poj2773 Happy 2006 二分+容斥原理
容斥原理可以明显的看的出 也算是模板题了
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<stack> 8 #include<queue> 9 #include<cmath> 10 using namespace std; 11 #define N 10000000000 12 #define LL long long 13 int p[32],g; 14 LL sum=0; 15 int gcd(int a,int b) 16 { 17 return b==0?a:gcd(b,a%b); 18 } 19 void dfs(int num,LL y,int i,LL n) 20 { 21 y = p[i]*y; 22 if(num%2==0) sum-=n/y; 23 else sum+=n/y; 24 for(int j = i+1 ; j <= g ; j++) 25 dfs(num+1,y,j,n); 26 } 27 int main() 28 { 29 int m,k,i; 30 while(cin>>m>>k) 31 { 32 g = 0; 33 for(i = 2; i <= m ;i++) 34 { 35 if(m%i==0) p[++g] = i; 36 while(m%i==0) 37 { 38 m/=i; 39 } 40 } 41 if(m!=1) p[++g] = m; 42 LL low = 1,high = N,mid; 43 LL ans; 44 while(low<=high) 45 { 46 mid = (low+high)/2; 47 sum=0; 48 for(i = 1; i <= g; i++) 49 { 50 dfs(1,1,i,mid); 51 } 52 /*if(mid-sum==k) 53 { 54 while(gcd(mid,k)!=1)mid--; 55 break; 56 }*/ 57 if(mid-sum<k) low = mid+1; 58 else {high = mid-1;} 59 } 60 cout<<low<<endl; 61 } 62 return 0; 63 }
这跳骚很牛X 。。特别能跳
这个可以想到 可以跳出相差为一的 就是gcd(x1,x2,,....xn) = 1,具体我也不知道怎么证 我是以欧几里得猜的 ax+by = gcd(x,y) 有解
这个题求补集 把每一次的减去
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 100000 12 #define LL __int64 13 #define INF 0xfffffff 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 int p[32]; 18 double ppow(int x,int n) 19 { 20 int i; 21 double s = 1; 22 for(i = 1; i <= n ;i++) 23 s*=x; 24 return s; 25 } 26 int main() 27 { 28 int i,j,n,m; 29 scanf("%d%d",&n,&m); 30 int g = 0; 31 int q = m; 32 for(i = 2 ; i*i <= m ;i++) 33 { 34 if(m%i==0) p[++g] = i; 35 while(m%i==0) 36 m/=i; 37 if(i>m) break; 38 } 39 if(m!=1) p[++g] = m; 40 double s = ppow(q*1.0,n); 41 for(i = 1 ; i < (1<<g) ; i++) 42 { 43 int o = 0,y=1; 44 for(j = 0 ; j < g ; j++) 45 { 46 if(i&(1<<j)) 47 { 48 o++; 49 y*=p[j+1]; 50 } 51 } 52 LL x = q/y; 53 if(o%2) s-=ppow(x,n); 54 else s+=ppow(x,n); 55 } 56 printf("%I64d\n",(LL)s); 57 return 0; 58 }
这个其实把最大公约数除去之后 求一下互质的个数 可能数据有点水吧 直接枚举每一个的与其互质的个数 然后加起来
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<cmath> 7 #include<vector> 8 using namespace std; 9 #define LL __int64 10 #define N 100010 11 LL o[N]; 12 int p[22]; 13 LL init(int s1,int s2) 14 { 15 int i,j,e; 16 LL cnt = 0; 17 for(i = s1 ; i >= 2 ; i--) 18 { 19 int g = 0,x=i; 20 for(j = 2 ; j*j <= x ; j++) 21 { 22 if(x%j==0){p[++g] = j;} 23 while(x%j==0) x/=j; 24 } 25 if(x!=1) p[++g] = x; 26 int ans = i+s2-s1; 27 for(j = 1 ; j < (1<<g) ; j++) 28 { 29 int s = 0,y=1; 30 for(e = 0 ; e < g ; e++) 31 { 32 if(j&(1<<e)) 33 { 34 s++; 35 y*=p[e+1]; 36 } 37 } 38 if(s%2) 39 { 40 ans-=i/y; ans-=(s2/y-s1/y); 41 } 42 else {ans+=i/y;ans+=(s2/y-s1/y); 43 } 44 } 45 cnt += ans; 46 } 47 return cnt+s2-s1+1; 48 } 49 int main() 50 { 51 int k,a,b,c,d; 52 int t,kk=0; 53 cin>>t; 54 while(t--) 55 { 56 scanf("%d%d%d%d%d",&a,&b,&c,&d,&k); 57 if(b>d) swap(b,d); 58 printf("Case %d: ",++kk); 59 if(k==0||b<k) 60 { 61 cout<<"0\n"; 62 continue; 63 } 64 cout<<init(b/k,d/k)<<endl; 65 } 66 return 0; 67 }
直接套模板
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdio> 5 #include<stdlib.h> 6 #include<cmath> 7 #include<vector> 8 using namespace std; 9 int k[10],o[10],num[10]; 10 int c1[55],c2[55]; 11 bool f[10]; 12 int main() 13 { 14 int i,j,a,b,n,k,t,e; 15 cin>>t; 16 while(t--) 17 { 18 memset(o,0,sizeof(o)); 19 memset(f,0,sizeof(f)); 20 memset(c1,0,sizeof(c1)); 21 memset(c2,0,sizeof(c2)); 22 cin>>n>>k; 23 int g = 0; 24 for(i = 1; i <= k ;i++) 25 { 26 cin>>a>>b; 27 o[a]+=b; 28 if(!f[b]) 29 { 30 num[++g] = a; 31 } 32 } 33 for(i = 0 ; i <= num[1]*o[num[1]] &&i<=n; i += num[1]) 34 c1[i] = 1; 35 for(i = 2 ; i <= g ;i++) 36 { 37 for(j = 0 ; j <= n ; j++) 38 for(e = 0 ; e+j<=n&&e <= num[i]*o[num[i]] ; e+=num[i]) 39 { 40 c2[j+e]+=c1[j]; 41 } 42 for(j = 0 ; j <= n ;j++) 43 { 44 c1[j] = c2[j]; 45 c2[j] = 0; 46 } 47 } 48 cout<<c1[n]<<endl; 49 } 50 return 0; 51 }
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define LL long long 12 #define INF 0xfffffff 13 const double eps = 1e-8; 14 const double pi = acos(-1.0); 15 const double inf = ~0u>>2; 16 double c1[22],c2[22]; 17 int b[12]; 18 int cn(int x) 19 { 20 int i,s=1; 21 for(i = 1; i <= x ; i++) 22 s*=i; 23 return s; 24 } 25 int main() 26 { 27 int i,j,n,m; 28 while(cin>>n>>m) 29 { 30 memset(c1,0,sizeof(c1)); 31 memset(c2,0,sizeof(c2)); 32 for(i = 1; i <= n; i++) 33 { 34 cin>>b[i]; 35 } 36 for(i = 0 ;i<=b[1] ;i++) 37 c1[i] = 1.0/cn(i); 38 for(i = 2; i <= n ;i++) 39 { 40 for(j = 0 ;j <= m ;j++) 41 { 42 for(int g = 0 ; g <= b[i] ; g++) 43 c2[j+g] += 1.0*c1[j]/cn(g); 44 } 45 for(j = 0 ; j <= m ;j++) 46 { 47 c1[j] = c2[j]; 48 c2[j] = 0; 49 } 50 } 51 printf("%0.lf\n",c1[m]*cn(m)); 52 } 53 return 0; 54 }
hdu 1812 polya 数太大直接用JAVA了
旋转 0 n*n
90 偶数 n*n/4 奇数 (n*n-1)/4
180 偶数 n*n/2 奇数 (n*n-1)/2
270 偶数 n*n/4 奇数 (n*n-1)/4
对角折 (n*n-n)/2+n 两次
中线折 偶数 (n*n)/2 奇数(n*n-n)/2+n 两次
1 import java.text.*; 2 import java.io.*; 3 import java.util.*; 4 import java.math.*; 5 import java.applet.*; 6 public class Main 7 { 8 public static void main(String args[]) 9 { 10 BigInteger cnt; 11 Scanner cin = new Scanner(System.in); 12 int i,j,n,m; 13 while(cin.hasNextInt()) 14 { 15 n = cin.nextInt(); 16 m = cin.nextInt(); 17 cnt = BigInteger.valueOf(0); 18 BigInteger bn = BigInteger.valueOf(m); 19 cnt = cnt.add(bn.pow(n*n)); 20 if(n%2==0) 21 { 22 cnt = cnt.add(bn.pow(n*n/4).multiply(BigInteger.valueOf(2))); 23 cnt = cnt.add(bn.pow(n*n/2)); 24 cnt = cnt.add(bn.pow((n*n-n)/2+n).multiply(BigInteger.valueOf(2))); 25 cnt = cnt.add(bn.pow(n*n/2).multiply(BigInteger.valueOf(2))); 26 } 27 else 28 { 29 cnt = cnt.add(bn.pow((n*n-1)/4+1).multiply(BigInteger.valueOf(2))); 30 cnt = cnt.add(bn.pow((n*n-1)/2+1)); 31 cnt = cnt.add(bn.pow((n*n-n)/2+n).multiply(BigInteger.valueOf(4))); 32 } 33 System.out.println(cnt.divide(BigInteger.valueOf(8))); 34 } 35 } 36 }
POJ 1286 Necklace of Beads 经典的polay计数
其实对于burnside不是特别的理解 只是大体的记得了公式 大体了解 知道哪一类题是用它来解的。 下面可能会把点说成珠子。。。
文库里讲的都很清楚 可以初步了解下 这个题大体说一下 抛开重复不说 对于每个点可以染k种颜色 那么可以染的可能为n^k 因为旋转或者翻转使得一些可能变成了相同的 这时候就要删除相同的 引入置换的概念 举个例子就是在某种置换下 a->b c->d 也就是说本来该是 4^k 现在对折置换之后 a与b c与d 其实是一样的 那么很明显就变成了2^k。
这个题 包括两种置换 一是 旋转置换 二是 翻转置换
对于旋转: 套定理 k^gcd(i,n) (0<i<=n)
对于翻转: 因为要对折 就要考虑奇数 和偶数 奇数: 沿穿过每个珠子的线对折 n个置换 ((n-1)/2+1)^k
偶数 沿穿过珠子的线 n/2个置换 ((n-2)/2+2)^k 不穿过珠子的线 n/2个置换 (n/2)^k
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 100000 12 #define LL long long 13 #define INF 0xfffffff 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 int gcd(int a,int b) 18 { 19 return b==0?a:gcd(b,a%b); 20 } 21 int main() 22 { 23 int i,n; 24 while(cin>>n) 25 { 26 if(n==-1) break; 27 LL s = 0; 28 if(n==0) 29 { 30 cout<<"0\n"; 31 continue; 32 } 33 for(i = 1 ; i <= n ;i++) 34 { 35 s+=(LL)pow(3.0,gcd(i,n)); 36 } 37 if(n%2==0) 38 cout<<(s+n/2*(LL)pow(3.0,(n-2)/2+2)+n/2*(LL)pow(3.0,n/2))/2/n<<endl; 39 else 40 cout<<(s+n*(LL)pow(3.0,(n-1)/2+1))/2/n<<endl; 41 } 42 return 0; 43 }
POJ 2409 Let it Bead 同上 其实上题的题解该是本题的 上一题的K就是为3
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 100000 12 #define LL long long 13 #define INF 0xfffffff 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 int gcd(int a,int b) 18 { 19 return b==0?a:gcd(b,a%b); 20 } 21 int main() 22 { 23 int i,n,k; 24 while(cin>>k>>n) 25 { 26 if(!n&&!k) break; 27 if(n==0) 28 { 29 cout<<"0\n"; 30 continue; 31 } 32 LL s = 0; 33 for(i = 1 ; i <= n ;i++) 34 { 35 s+=(LL)pow(k*1.0,gcd(i,n)); 36 } 37 if(n%2==0) 38 cout<<(s+n/2*(LL)pow(k*1.0,(n-2)/2+2)+n/2*(LL)pow(k*1.0,n/2))/2/n<<endl; 39 else 40 cout<<(s+n*(LL)pow(k*1.0,(n-1)/2+1))/2/n<<endl; 41 } 42 return 0; 43 }
POJ 1026 Cipher 这个属于置换群的题 找出循环节 总循环节就等于lcm(x1,x2,x3) 所有的循环节的最小公倍数
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<cmath> 7 using namespace std; 8 #define LL long long 9 LL gcd(LL a,LL b) 10 { 11 return b==0?a:gcd(b,a%b); 12 } 13 char s[210],ss[210]; 14 int a[210],q[210][210],o[210]; 15 int b[210]; 16 bool vis[210]; 17 int main() 18 { 19 int i,j,n,m; 20 while(cin>>n) 21 { 22 if(!n) break; 23 memset(vis,0,sizeof(vis)); 24 for(i = 1; i <= n ;i++) 25 scanf("%d",&a[i]); 26 int kk = 0; 27 for(i = 1; i <= n; i++) 28 { 29 if(!vis[i]) 30 { 31 kk++; 32 int g = 0; 33 q[kk][++g] = i; 34 vis[i]=1; 35 int x = a[i]; 36 while(!vis[x]) 37 { 38 vis[x] = 1; 39 q[kk][++g] = x; 40 x = a[x]; 41 } 42 o[kk] = g; 43 } 44 } 45 LL lcm = 1; 46 for(i = 1; i <= kk ; i++) 47 { 48 lcm = lcm/gcd(lcm,o[i])*o[i]; 49 } 50 while(scanf("%d%*c",&m)!=EOF) 51 { 52 if(!m) break; 53 gets(s); 54 int k = strlen(s); 55 for(i = k ; i < n ;i++) 56 s[i] = ' '; 57 s[n] = '\0'; 58 m = m%lcm; 59 for(i = 1; i <= kk ;i++) 60 { 61 int ko = m%o[i]; 62 for(j = 1; j <= o[i] ; j++) 63 { 64 if(j+ko<=o[i]) 65 b[q[i][j]] = q[i][j+ko]; 66 else 67 { 68 b[q[i][j]] = q[i][j+ko-o[i]]; 69 } 70 } 71 } 72 for(i = 0 ;i < n ; i++) 73 { 74 ss[b[i+1]] = s[i]; 75 } 76 for(i = 1 ;i <= n ;i++) 77 printf("%c",ss[i]); 78 puts(""); 79 } 80 puts(""); 81 } 82 return 0; 83 }
POJ 1721 CARDS 这个题说是置换幂的应用 也是先找出循环节 然后减去m次(这里根据长度 变换一下) 就是逆运算 变回去
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<cmath> 7 #include<vector> 8 using namespace std; 9 #define N 1010 10 int a[N],b[N][N]; 11 int main() 12 { 13 int i,j,n,m; 14 while(scanf("%d%d",&n,&m)!=EOF) 15 { 16 for(i = 1; i <= n ;i++) 17 { 18 scanf("%d",&a[i]); 19 b[1][i] = a[i]; 20 } 21 for(i = 2; ; i++) 22 { 23 for(j = 1; j <= n ;j++) 24 { 25 b[i][j] = b[i-1][b[i-1][j]]; 26 } 27 /*for(j = 1; j <= n ;j++) 28 cout<<b[i][j]<<" "; 29 puts("");*/ 30 for(j = 1; j <= n ;j++) 31 { 32 if(b[i][j]!=b[1][j]) break; 33 } 34 35 if(j==n+1) break; 36 } 37 int k = i-1; 38 m = m%k; 39 //cout<<m<<endl; 40 for(i = 1; i <= n; i++) 41 printf("%d\n",b[k+1-m][i]); 42 } 43 return 0; 44 }
POJ 3128 Leonardo's Notebook 算是置换开方的应用 有结论是 偶数度的循环节是可以由两个相同偶数度的结合而来 奇数则有奇数而来 具体看一下置换群快速幂运算的研究吧
这样就可以在给出的串中找每个循环(也称置换也称轮换)的循环节 看偶数度的是否是成对出现 是 则一定可以有某个置换平方而来 不然则不可以
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 100000 12 #define LL long long 13 #define INF 0xfffffff 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 char s[30],ss[30]; 18 int p[500]; 19 bool vis[500]; 20 int main() 21 { 22 int i,j,n; 23 cin>>n; 24 while(n--) 25 { 26 memset(vis,0,sizeof(vis)); 27 memset(p,0,sizeof(p)); 28 cin>>s; 29 for(i = 0 ;i < strlen(s) ; i++) 30 { 31 if(!vis[i]) 32 { 33 vis[i] = 1; 34 j = s[i]-'A'; 35 int o = 1; 36 while(!vis[j]) 37 { 38 vis[j] = 1; 39 j = s[j]-'A'; 40 o++; 41 } 42 p[o]++; 43 } 44 } 45 int ans=0; 46 for(i = 2; i <= 26 ; i+=2) 47 if(p[i]%2) break; 48 if(i<=26) puts("No"); 49 else puts("Yes"); 50 } 51 return 0; 52 }
POJ 3590 The shuffle Problem 也是属于置换 不过涉及到最小公倍数最小 即总循环节最小 要把整数拆分为最小公倍数最大 我用dp+置换解的
先dp出最小公倍数最大的解 然后依次枚举字典序最小 也就是前几块分割长度越小越好
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<stdlib.h> 6 #include<vector> 7 #include<cmath> 8 #include<queue> 9 #include<set> 10 using namespace std; 11 #define N 100000 12 #define LL long long 13 #define INF 0xfffffff 14 const double eps = 1e-8; 15 const double pi = acos(-1.0); 16 const double inf = ~0u>>2; 17 int p[110],g,b[110]; 18 LL dp[110][110]; 19 int o[110][110],sum[110]; 20 int w[110],pp[110],q[110]; 21 LL gcd(LL a,LL b) 22 { 23 return b==0?a:gcd(b,a%b); 24 } 25 void init(int n) 26 { 27 int i,j; 28 sum[0] = 0; 29 for(i = 1; i <= n ;i++) 30 { 31 sum[i] = sum[i-1]+1; 32 dp[1][i] = sum[i]; 33 } 34 for(i = 2; i <= n ; i++) 35 for(j = n; j >= 1 ; j--) 36 for(g = 1; g < j; g++) 37 { 38 LL k = dp[i-1][g]/gcd(dp[i-1][g],sum[j]-sum[g])*(sum[j]-sum[g]); 39 if(dp[i][j]<=k) 40 { 41 dp[i][j] =k; 42 o[i][j] = g; 43 } 44 } 45 } 46 int main() 47 { 48 int i,j,n,t; 49 cin>>t; 50 while(t--) 51 { 52 cin>>n; 53 memset(dp,0,sizeof(dp)); 54 init(n); 55 LL ans = 1; 56 LL maxz = 0; 57 int x; 58 pp[0] = n; 59 for(i = 1; i <= n ;i++) 60 { 61 if(maxz<=dp[i][n]) 62 { 63 x = i; 64 maxz = dp[i][n]; 65 } 66 pp[i] = n; 67 } 68 int gg; 69 for(i = 2; i <= n;i++) 70 { 71 if(dp[i][n]==maxz) 72 { 73 int g = 0; 74 x = i; 75 int y = o[x][n]; 76 p[++g] = y;x--; 77 while(x!=1) 78 { 79 y = o[x][y]; 80 p[++g] = y; 81 x--; 82 } 83 int l=0; 84 p[g+1] = 0; 85 p[0] = n; 86 for(j = 1 ; j <=g+1 ; j++) 87 { 88 q[l++] = p[j-1]-p[j]; 89 } 90 91 sort(q,q+l); 92 int f = 1; 93 for(j = 0 ;j < l ;j++) 94 { 95 if(q[j]>pp[j]) { 96 f = 0; 97 break; 98 } 99 else if(q[j]<pp[j]) break; 100 } 101 if(f) 102 { 103 gg = l; 104 for(j = 0; j < l ;j++) 105 pp[j] = q[j]; 106 } 107 } 108 109 } 110 cout<<maxz<<" "; 111 int tt=0; 112 for(i = 0; i < gg ; i++) 113 { 114 for(j = tt+1 ; j <= tt+pp[i]; j++) 115 { 116 if(j+1<=pp[i]+tt) 117 b[j] = j+1; 118 else 119 b[j] = tt+1; 120 } 121 tt+=pp[i]; 122 } 123 if(n==1) b[1] = 1; 124 for(i = 1; i < n; i++) 125 cout<<b[i]<<" "; 126 cout<<b[n]<<endl; 127 } 128 return 0; 129 }