我连作业都没写就跑过来写题解了,足以看出我对信竞深沉的热爱。

好吧,其实都是假象,我只是单纯不想写作业过来消磨时间而已。

然后下面就是我的题解。由于我家的电脑坏了,所以我的程序好像都编译不了,这就导致我目前为止也不知道自己改的对不对(滑稽),如果全错了那也是很正常的,请大家不要嫌弃

.......

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("\n");
    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("\n");
    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("\n");
	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("\n");
    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("\n");
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 }