我连作业都没写就跑过来写题解了,足以看出我对信竞深沉的热爱。
好吧,其实都是假象,我只是单纯不想写作业过来消磨时间而已。
然后下面就是我的题解。由于我家的电脑坏了,所以我的程序好像都编译不了,这就导致我目前为止也不知道自己改的对不对(滑稽),如果全错了那也是很正常的,请大家不要嫌弃
.......
1.无重复数字的全排列
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int vis[13],a[13]; int m = 1,s = 1,y = 1,n; int printf() { printf("%d:",m); for(int i = 1;i <= n;i++) { printf("%d ",a[i]); } printf(" "); m++; } int dfs(int y) { for(int i = 1;i <= n;i++) { if(vis[i] == 0)//如果这个点没有被访问过,那就访问这个点 { vis[i] = 1; a[y] = i;//即便将a[y]赋的值不成立也没关系,下次再搜索到这的时候会把它改成一个成立的值 dfs(y + 1); vis[i] = 0; } } if(y == n) printf();//当排列中数达到n时,输出这个排列 } int main() { freopen("p1.in","r",stdin); freopen("p1.out","w",stdout); scanf("%d",&n); dfs(1); return 0; }
2.无重复元素的全排列
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; char a[15],c[15]; int b[15]; int m,y = 1; int printf() { printf("%d:",y); for(int i = 1;i <= m;i++) { printf("%d",c[i]); } printf(" "); y++; } int search(int x) { for(int i = 1;i <= n;i++) { if(b[i] == 0) { b[i] = 1; c[x] = i; search(x + 1); b[i] = 0; } } if(x == m) printf(); } int main() { //freopen("p2.in","r",stdin); //freopen("p2.out","w",stdout); scanf("%s",a); m = strlen(a); sort(a + 1,a + m + 1); search(1); return 0; }
3.有重复元素的全排列
4.无重复元素的组合
5.有重复元素的组合
6.正常的分解
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int n,m,y = 1; int printf(int t) { printf("%d:%d = ",&y,&n); for(int i = 1;i <= t;i++) { printf("%d",a[i]); if(i < n) printf(" + "); } printf(" "); y++; } int search(int s,int x,int t) { for(int i = a[t - 1];i <= min(x,s);i++) //其他的好像都跟第六题差不多,就是最终要保证每一项都在大于前一项的同时分别小于m和剩下的s值 { a[t] = i; s = s - i; if(s == 0) printf(t); else search(s,x,t + 1); s = s + i; } } int main() { //freopen("p7.in","r",stdin); //freopen("p7.out","w",stdout); scanf("%d%d",&n,&m); search(n,m,1); return 0; }
7.每一项都不超过m的分解
#include<cstdio> #include<cstring> #include<cmath> #include<iostream> #include<algorithm> using namespace std; int n,m,y = 1; int printf(int t) { printf("%d:%d = ",&y,&n); for(int i = 1;i <= t;i++) { printf("%d",a[i]); if(i < n) printf(" + "); } printf(" "); y++; } int search(int s,int x,int t) { for(int i = a[t - 1];i <= min(x,s);i++) //其他的好像都跟第六题差不多,就是最终要保证每一项都在大于前一项的同时分别小于m和剩下的s值 { a[t] = i; s = s - i; if(s == 0) printf(t); else search(s,x,t + 1); s = s + i; } } int main() { //freopen("p7.in","r",stdin); //freopen("p7.out","w",stdout); scanf("%d%d",&n,&m); search(n,m,1); return 0; }
8.分解项数不超过m的分解
1 #include<cstdio> 2 #include<cstring> 3 #include<cmath> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 int n,m,y; 8 int printf() 9 { 10 printf("%d:%d = ",&y,&n); 11 for(int i = 1;i <= m;i++) 12 { 13 printf("%d",a[i]); 14 if(i < n) printf(" + "); 15 } 16 printf(" "); 17 y++; 18 } 19 int search(int s,int x,int t) 20 { 21 for(int i = a[t - 1];i <= s;i++) 22 { 23 if(t > m) break;//当t大于m的时候就跳过这次搜索进入下一位继续搜索 24 a[t] = i; 25 s = s - i; 26 if(s == 0) printf(); 27 else search(s,m,t); 28 s = s + i; 29 t = t - 1; 30 } 31 } 32 int main() 33 { 34 //freopen("p8.in","r",stdin); 35 //freopen("p8.out","w",stdout); 36 scanf("%d %d",&n,&m); 37 search(); 38 return 0; 39 }