暴力枚举(部分

P2089
其实第一个想法应该是十个循环

#include<iostream>  
using namespace std;  
int main()  
{  
    int a,b,c,d,e,f,g,h,i,j,in,x=0;  
    cin>>in;  
    for (a=1;a<=3;a++)  
    {  
        for (b=1;b<=3;b++)  
        {  
            for (c=1;c<=3;c++)  
            {  
                for (d=1;d<=3;d++)  
                {  
                    for (e=1;e<=3;e++)  
                    {  
                        for (f=1;f<=3;f++)  
                        {  
                            for (g=1;g<=3;g++)  
                            {  
                                for(h=1;h<=3;h++)  
                                {  
                                    for (i=1;i<=3;i++)  
                                    {  
                                        for (j=1;j<=3;j++)  
                                        {  
                                            if (a+b+c+d+e+f+g+h+i+j==in)  
                                            {  
                                                x++;  
                                            }  
                                        }  
                                    }  
                                }  
                            }  
                        }  
                    }  
                }  
            }  
        }  
    }  
    cout<<x<<endl;  
    for (a=1;a<=3;a++)  
    {  
        for (b=1;b<=3;b++)  
        {  
            for (c=1;c<=3;c++)  
            {  
                for (d=1;d<=3;d++)  
                {  
                    for (e=1;e<=3;e++)  
                    {  
                        for (f=1;f<=3;f++)  
                        {  
                            for (g=1;g<=3;g++)  
                            {  
                                for(h=1;h<=3;h++)  
                                {  
                                    for (i=1;i<=3;i++)  
                                    {  
                                        for (j=1;j<=3;j++)  
                                        {  
                                            if (a+b+c+d+e+f+g+h+i+j==in)  
                                            {  
                                                cout<<a<<" ";  
                                                cout<<b<<" ";  
                                                cout<<c<<" ";  
                                                cout<<d<<" ";  
                                                cout<<e<<" ";  
                                                cout<<f<<" ";  
                                                cout<<g<<" ";  
                                                cout<<h<<" ";  
                                                cout<<i<<" ";  
                                                cout<<j<<endl;  
                                            }  
                                        }  
                                    }  
                                }  
                            }  
                        }  
                    }  
                }  
            }  
        }  
    }  
}  
//so beautiful!

然后递归是可以代替循环的,两个参数,一个就是循环的次数,还有一个是目前为止的和,然后用一个循环

#include<iostream>
using namespace std;
int n,kind=0,m1[10000][10],m2[10];
void peiliao(int total,int a){
    if (a==10){
        if (total==n) {
            for (int j=0;j<10;j++) m1[kind][j]=m2[j];//符合要求存起来~~ 
            kind++;
        }
    }
    else if (total>=n) ;//小小优化一下 
    else
      for (int i=1;i<=3;i++){
          m2[a]=i;
          peiliao(total+i,a+1);//其实这和十连for没什么区别。。。 
      }
}
int main(){
    cin>>n;
    peiliao(0,0);
    cout<<kind<<endl;
    for (int j=0;j<kind;j++){
      for (int i=0;i<10;i++) cout<<m1[j][i]<<" "; //大家一定要记得打空格... 
     cout<<endl; 
    }
    return 0;
}

值得注意的是,他要输出的应该是个二维数组,所以递归重点要把他们存起来,kind++

P1618
这道题在紫皮书上看到了,但还是写的时候遇到困难了,其实最重要的是枚举然后村数组,验证他们九个数字,数组可以用桶的思想

#include<iostream>
using namespace std;
int main()
{
	int a,b,c,arr[10]={0},m=0,j=0,q,w,e,t=0,f;
	scanf("%d%d%d",&a,&b,&c);
	for(int i=1;i<987;i++)
	{
		q=i*a;
		if(q<=987)
		{arr[q/100]++;
		arr[q%10]++;
		arr[q/10%10]++;
		}
		
		w=i*b;
		if(w<=987)
		{arr[w/100]++;
		arr[w%10]++;
		arr[w/10%10]++;
		}
		
		e=i*c; 
		if(e<=987)
		{
		arr[e/100]++;
		arr[e%10]++;
		arr[e/10%10]++;
		}
		
		for(int j=1;j<=9;j++)
		{
			if(arr[j]==0)
			break;
		}
		if(j>=10)
		{
		printf("%d %d %d\n",q,w,e);
		t=1;	
		}
		
		for(int p=1;p<=9;p++)
		{
			arr[p]=0;
		}
	}
	if(t==0)
	printf("No!!!");
	return 0;
	
}

P1036
难度在选数上面吧,for+递归,或许你可以把for的起始数也放进去,这样就不用设标志了

#include<bits/stdc++.h>
using namespace std;
int r,a[100],n;
void dfs(int k){//搜索第k个数
    int i;
    if(k>r){
        for(i=1;i<=r;i++){
            cout<<setw(3)<<a[i];//输出,场宽为三
        }
        cout<<endl;
        return ;//回到前一层
    }
    for(i=a[k-1]+1;i<=n;i++){
        a[k]=i;
        dfs(k+1);//直接进行下一次调用
    }
}  
int main()  
{   
    cin>>n>>r;
    dfs(1);
    return 0;  
}  

看解答的时候get到了stl的next_permutation

#include <iostream>  
#include <algorithm>  
using namespace std;  
int main()  
{  
    int num[3]={1,2,3};  
    do  
    {  
        cout<<num[0]<<" "<<num[1]<<" "<<num[2]<<endl;  
    }while(next_permutation(num,num+3));  
    return 0;  
}  
 

输出结果是123 132 213 231 312 321

当把3变成2 123 213
所以 next_permutation(num,num+n)
对前n个元素进行全排列
tip:需要对前n个进行升序,否则就会只出现部分

#include<cstdio>
#include<algorithm>
#define rep(a,b,c) for(register int a=b;a<=c;a++)
using namespace std;
int x[11];
int main()
{
    int n;scanf("%d",&n);rep(i,1,n) x[i]=i,printf("    %d",i);
    while(next_permutation(x+1,x+1+n)){printf("\n");rep(i,1,n) printf("    %d",x[i]);}
}

P3392
完蛋,再看已经不记得了

#include<iostream>
#include<math.h>
using namespace std;
int m,n;
char a[55][55];
int js(int u,int r,char pp)
{
	int sum=0,i,j;
	for(i=u;i<=r;i++)
	{
		for(j=1;j<=m;j++)
		sum+=a[i][j]!=pp;
		
	}
	return sum;
}
int main()
{
	int i,j,mn=2500;
	cin>>n>>m; 
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>a[i][j];
		}
	}
	for(int i=1;i<=n-2;i++)
	{
		for(int j=1+i;j<=n-1;j++)
		mn=min(mn,js(1,i,'W')+js(i+1,j,'B')+js(j+1,n,'R'));
		
	}
	cout<<mn;
	return 0;
 } 

先是输入各个char,然后开始快乐枚举,枚举什么呢,就是不同的头尾下,需要更改的颜色,那么就需要一个两重循环,目的是让尾巴随着头改变,在这样的循环下,调用函数,函数内部是个循环,两个参数决定循环次数,内部循环是一列上的,然后有个很神奇的

sum+=a[i][j]!=pp;

这是个逻辑运算!!!

P2036
dfs(目前的配料编号,酸度,甜度)
注意(i>n)才算读完,还要判断清水情况,两种情况深搜,添加与不添加,就写出来好了,反正后面是有比较的

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int M=15;//养成良好习惯
int a[M],b[M],n,ans=0x7f;
//ans初始化为最大值
void dfs(int i,int x,int y){
//i是表示目前的配料编号,x为酸度,y为甜度
    if(i>n){
    	//注意,必须大于n才表示全部搜完
        if(x==1&&y==0)return;
        //判断清水的情况
        ans=min(abs(x-y),ans);
        //更新ans
        return;
    }
    //分两种情况搜索:1添加 2不添加
    dfs(i+1,x*a[i],y+b[i]);
    dfs(i+1,x,y); 
    //这题无需回溯,不明白为何有些题解居然还用全局变量,非得回溯-_-||
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d%d",&a[i],&b[i]);
        //读入,用cin太慢了
    }
    dfs(1,1,0);
    printf("%d\n",ans);
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值