赞
踩
目录
- #include <bits/stdc++.h>
- using namespace std;
-
- int a[10]={1,2,3,4,5,6,7,8,9,10};
- int b[10];
- bool vis[10];
-
- void dfs(int s)
- {
- if(s==6)
- {
- for(int i=0;i<6;i++)
- {
- cout<<b[i]<<' ';
- }
- cout<<endl;
- return;
- }
- for(int i=0;i<6;i++)
- {
- if(!vis[i])
- {
- vis[i]=true;
- b[s]=a[i];
- dfs(s+1);
- vis[i]=false;
- }
- }
- }
-
- int main()
- {
- dfs(0);
- return 0;
- }
特点:充分运用全排列知识,每一行只能放一个皇后,全排列保证每一列只能出现一个皇后,斜线再进行后续处理
特点:在n皇后的基础上需要再次运用全排列,属于嵌套搜索
原题:
- #include <bits/stdc++.h>
- using namespace std;
-
- int mp[9][9];//初始化地图
- bool visblack[9];//黑皇后是否用到
- bool viswhite[9];//白皇后是否用到
- int black[9],white[9];//皇后放到第几列 *解释1*
- int ans;//答案
- int cnt,cnt1,cnt2,n,jishu[30],temp;//计数用
- int j,i;//循环变量
- void dfswhite(int p)//后放
- {
- if(p==n+1)//设置边界
- {
- cnt=0,cnt1=0,cnt2=0,temp=0;//计数用的变量必须归零
- memset(jishu,0,sizeof(jishu));
- for(int j=1;j<=n;j++)
- {
- if(mp[j][white[j]]==1)//检测该位置是否能放皇后
- {
- cnt++;
- }
- for(int k=0;k<=n-1;k++)//*解释2* *解释3*
- {
- if(j+white[j]==n+1+k) jishu[k]++;//0ton-1
- }
- for(int k=1;k<=n-1;k++)
- {
- if(j+white[j]==n+1-k) jishu[n+k-1]++;//nto2n-2
- }
- for(int k=0;k<=n-1;k++)
- {
- if(white[j]==j+k) jishu[2*n-1+k]++;//2n-1to3n-1
- }
- for(int k=1;k<=n-1;k++)
- {
- if(white[j]==j-k) jishu[3*n+k-2]++;//3nto4n-1
- }
- }
- /*for(int j=1;j<=50;j++)//测试用
- {
- cout<<jishu[j]<<' ';
- }
- cout<<endl;*/
- for(int k=0;k<=29;k++)
- {
- if(jishu[k]>=2) cnt--;
- }
- if(cnt==n)
- {
- /*for(int j=1;j<=n;j++)
- {
- cout<<"bai"<<white[j]<<' ';
- }
- cout<<endl;*/
- ans++;
- }
- return;
- }
-
- for(int i=1;i<=n;i++)//dfs全排列*解释4*
- {
- if(!viswhite[i])
- {
- viswhite[i]=true;
- white[p]=i;
- dfswhite(p+1);
- viswhite[i]=false;
- }
- }
- return;
- }
-
- void dfsblack(int s)//先放
- {
- if(s==n+1)
- {
- cnt=0,cnt1=0,cnt2=0,temp=0;
- memset(jishu,0,sizeof(jishu));
- for(int i=1;i<=n;i++)
- {
- if(mp[i][black[i]]==1)
- {
- cnt++;
- }
- for(int k=0;k<=n-1;k++)
- {
- if(i+black[i]==n+1+k) jishu[k]++;
- }
- for(int k=1;k<=n-1;k++)
- {
- if(i+black[i]==n+1-k) jishu[n+k-1]++;
- }
- for(int k=0;k<=n-1;k++)
- {
- if(black[i]==i+k) jishu[2*n-1+k]++;
- }
- for(int k=1;k<=n-1;k++)
- {
- if(black[i]==i-k) jishu[3*n+k-2]++;
- }
- }
- /*for(int j=1;j<=50;j++)
- {
- cout<<jishu[j]<<' ';
- }
- cout<<endl;*/
- for(int k=0;k<=29;k++)
- {
- if(jishu[k]>=2) cnt--;
- }
- if(cnt==n)
- {
- /*for(int i=1;i<=n;i++)
- {
- cout<<"hei"<<black[i]<<' ';
- }
- cout<<endl;*/
- for(int i=1;i<=n;i++)
- {
- mp[i][black[i]]=0;
- }
- //cout<<"开始"<<endl;
- dfswhite(1);
- //cout<<"结束"<<endl;
- for(int i=1;i<=n;i++)
- {
- mp[i][black[i]]=1;
- }
- }
- return;
- }
-
- for(int i=1;i<=n;i++)
- {
- if(!visblack[i])
- {
- visblack[i]=true;
- black[s]=i;
- dfsblack(s+1);
- visblack[i]=false;
- }
- }
- return;
- }
-
- int main()
- {
- cin>>n;
- for(int i=1;i<=n;i++)
- {
- for(int j=1;j<=n;j++)
- {
- cin>>mp[i][j];
- }
- }
- dfsblack(1);
- cout<<ans;
- return 0;
- }
特点:在n皇后问题上进行修改,不限制放置数量,需要搜索次数更多
原题:
- #include <bits/stdc++.h>
- using namespace std;
- int N;
- long long ans=0;
- bool vis[10];
- void dfs(int s)
- {
- if(s>N)
- {
- ans++;
- return ;
- }
- for(int i=1;i<=N;i++)
- {
- if(!vis[i])
- {
- vis[i]=true;
-
- dfs(s+1);
- vis[i]=false;
- }
- }
- dfs(s+1); //不一定从第s行开始放(即第s行没有也可以),从s+1行开始放也可以
- }
- int main()
- {
- cin>>N;
- dfs(1);
- cout<<ans;
- return 0;
- }
-
特点:把n个数据放入m个位置中加和(其中n>m)
原题:
- #include<bits/stdc++.h>
- using namespace std;
- int a[10];
- int n,m;
- int ans=INT_MAX;
- bool vis[10];
- int sum[10];
- void dfs(int k)
- {
- if(k>=n+1)
- {
- int maxsum=0,minsum=INT_MAX;
- for(int i=1;i<=m;i++)
- {
- maxsum=max(maxsum,sum[i]);
- minsum=min(minsum,sum[i]);
- }
- ans=min(maxsum-minsum,ans);
- return ;
- }
- for(int i=k;i<=n;i++) //注意这个地方是从k开始的,防止重复计算,剪枝,否则得90分
- {
- if(!vis[i])
- {
- vis[i]=true;
- for(int j=1;j<=m;j++)
- {
- sum[j]+=a[i];
- dfs(k+1);
- sum[j]-=a[i];
- }
- vis[i]=false;
- }
- }
- }
- int main()
- {
- cin>>n>>m;
- for(int i=1;i<=n;i++)
- {
- cin>>a[i];
- }
- dfs(1);
- cout<<ans;
- return 0;
- }
特点:需要两个数两个数搜索
原题:
- #include <bits/stdc++.h>
- using namespace std;
-
- int n;
- int nums[4];
- int ans;
-
- void f(int nums[], int n)
- {
-
- if(n==1)//边界
- {
- if(nums[n-1]<=24)
- {
- ans=max(ans,nums[n-1]);
- }
- return ;
- }
-
- //遍历两个数的组合
- for(int i=0; i<n-1; i++)
- {
- for(int j=i+1; j<n; j++)
- {
- int a=nums[i], b=nums[j];
-
- nums[j] = a + b;//不断计算当前值放给nums[j]
- nums[i] = nums[n-1];//不断把未计算的值放给nums[i]
- f(nums, n-1);
-
- nums[j] = a * b;
- nums[i] = nums[n-1];
- f(nums, n-1);
-
- nums[j] = a - b;
- nums[i] = nums[n-1];
- f(nums, n-1);
-
- nums[j] = b - a;
- nums[i] = nums[n-1];
- f(nums, n-1);
-
- if(b!=0 && a%b==0)
- {
- nums[j] = a / b;
- nums[i] = nums[n-1];
- f(nums, n-1);
- }
-
- if(a!=0 && b%a==0)
- {
- nums[j] = b / a;
- nums[i] = nums[n-1];
- f(nums, n-1);
- }
-
- nums[i] = a;//回溯
- nums[j] = b;
- }
- }
- }
-
- int main()
- {
- cin>>n;
- for(int i=0; i<n; i++)
- {
- for(int j=0; j<4; j++)
- {
- cin >> nums[j];
- }
- ans = 0;
- f(nums, 4);
- cout<<ans<<endl;
- }
- return 0;
- }
特点:全排列+筛选
- #include <bits/stdc++.h>
- using namespace std;
- int a[10]={1,2,3,4,5,6,8,9,10,12};
- int b[10];
- bool vis[10];
- int ans;
- void dfs(int s,int step)
- {
- if(s==step)
- {
- /*for(int i=0;i<step;i++)
- {
- printf("%d ",b[i]);
- }
- printf("\n");*/
- int t=b[0]+b[2]+b[5]+b[8];
- if(t==b[0]+b[3]+b[6]+b[9]&&t==b[1]+b[2]+b[3]+b[4]&&t==b[1]+b[5]+b[7]+b[9]&&t==b[4]+b[6]+b[7]+b[8]) ans++;
- }
- for(int i=0;i<10;i++)
- {
- if(!vis[i])
- {
- vis[i]=true;
- b[s]=a[i];
- dfs(s+1,step);
- vis[i]=false;
- }
- }
- }
-
- int main()
- {
- dfs(0,10);
- printf("%d",ans/10);
- return 0;
- }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。