C/C++
暴力求解法
暴力枚举之除法
将0-9分成五个五个一组,abcde/fghij=n,指定n求出所有符合的元素,从小到大输出。
从01234开始枚举。
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int main()
{
int n,kase=0;
while(scanf("%d",&n)==1 && n)
{
if(kase++)printf("\n");
int cnt=0;
for(int fghij=1234;;fghij++)
{
char buf[99];
int abcde=n*fghij;
sprintf(buf,"%05d%05d",abcde,fghij);//五个一组输出到buf中
if(strlen(buf)>10) break;
sort(buf,buf+10);
bool ok=true;
for(int i=0;i<10;i++)
{
if(buf[i]!='0'+i)ok=false;
}
if(ok)
{
printf("%05d / %05d = %d\n",abcde,fghij,n);
cnt++;
}
}
if(!cnt)printf("There are no solutions for %d.\n", n);
}
return 0;
}
暴力枚举之寻找最大子序列乘积
在连续子序列之中,寻找乘积最大的序列,遍历所有的起点和终点即可。
#include<iostream>
using namespace std;
int main() {
int S[20], kase = 0, n;
while(cin >> n && n) {
for(int i = 0; i < n; i++) cin >> S[i];
long long ans = 0;
for(int i = 0; i < n; i++) //起点
{
long long v = 1;
for(int j = i; j < n; j++) //终点
{
v *= S[j];
if(v > ans) ans = v;
}
}
cout << "Case #" << ++kase << ": The maximum product is " << ans << ".\n\n";
}
return 0;
}
暴力枚举之分数拆分
输入正整数k,找到所有正整数x>=y,使得1/k=1/x+1/y
从y=k+1开始遍历,最后一个表达式肯定是y=2*k=x.
#include<iostream>
#include<cstdio>
#include<vector>
using namespace std;
int main()
{
int k;
while(cin>>k)
{
vector<int> sy,sx;
int x;
for(int y=k+1;y<=2*k;y++)
{
x=(k*y)/(y-k);
if(x>=y && (k*y)%(y-k)==0)
{
sx.push_back(x);
sy.push_back(y);
}
if(x<y) break;
}
cout<<sx.size()<<endl;
for(int i=0;i<sx.size();i++)
printf("1/%d = 1/%d + 1/%d\n",k,sx[i],sy[i]);
}
return 0;
}
暴力枚举之数据排列(递归1-n的元素字典序排列)
1-n个元素,不含重复元素存放在数组中,第一个元素有n种可能,每一种可能对应的下一个元素又有n-1种可能…符合递归的思想。一共有n的阶乘种排列。
像这种方法就是递归枚举法,工作方式就是解答树,第一层一个节点,第二层n个节点,第三次n(n-1)个节点,第n层n的阶乘个节点,就是栈帧的调用方式。
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
void print_permutation(int n,int* A,int cur)
{
if(cur==n)
{
for(int i=0;i<n;i++)printf("%d",A[i]);
printf("\n");
}
else for(int i=1;i<=n;i++)//从1-n开始选数,遍历,每个数都插入到该位置
{
int ok=1;
for(int j=0;j<cur;j++)
if(A[j]==i)ok=0;
if(ok){
A[cur]=i;
print_permutation(n,A,cur+1);
}
}
}
int main()
{
int n;
cin>>n;
int A[1000];
memset(A,0,sizeof(A));
print_permutation(n,A,0);
return 0;
}
暴力枚举之数据排列(STL中算法库next_permutation函数)
可以包含重复元素。
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n,p[10];
cin>>n;
for(int i=0;i<n;i++)
cin>>p[i];
sort(p,p+n);
do{
for(int i=0;i<n;i++)
cout<<p[i];
cout<<endl;
}while(next_permutation(p,p+n));
return 0;
}
暴力枚举之求子集(二进制法,当n<15时采用)
给定一个集合,不重复,求出该集合的所有子集,包含空集。
可以定义一个与该集合相同长度的数组,每个数组的元素为0或1,遍历0~2^n - 1(即i<<n-1)次即可得到所有情况下的子集编码。
将这个子集编码分别与所有元素进行按位与,为1即可输出该元素。就是将所有元素在数组中与子集编码相同的位置置为1(1<<i,代表将第几号位置置1,其他位置为0,本来就不用考虑其他位置),这样就只与子集编码有关了,是1即可输出。(注意是从右向左进行与,因为最右边值最小)