暴力求解法
一.简单枚举
第一题:除法
#include <cstdio>
#include <iostream>
using namespace std;
void dd(int n)
{
for (int i = 98765 / 79; i <= 98765 / 2; i++)//i是被除数
{
int y[12] = { 0 };
if (i < 10000)
{
y[0] = 1;
}
int k = i;//对当前数进行分解
int p;
bool isok = true;
do {
int temp = k % 10;
if (y[temp] == 1)
{
isok = false; break;
}
else {
y[temp] = 1;
}
k /= 10;
} while (k);
if (isok == false)
{
continue;
}
else
{
p = n * i;
int pp = p;
do {
int temp = pp % 10;
if (1 == y[temp]) {
isok = false; break;
}
else {
y[temp] = 1;
}
pp /= 10;
} while (pp);
}
if (isok)
{
if (i < 10000)
{
printf("%d/0%d=%d\n", p, i, n);
}
else {
printf("%d/%d=%d\n",p, i, n);
}
}
}
}
int main()
{
int n;
cin >> n;
//scanf_s("%d", &n);
dd(n);
return 0;
}
第二题:最大乘积
int main() {
int n;
cin >> n;
int aa[20]; int i;
for (i = 0; i < n; i++)
{
cin >> aa[i];
}
long long max = aa[0] * aa[1];
for (int begin = 0; begin <=i- 1; begin++)
{
for (int end = begin + 1; end <=i; end++)
{
long long p = 1;
for (int j = begin; j <end; j++)
{
p *= aa[j];
}
if (p > max)
{
max = p;
}
}
}
if (max < 0)
{
cout << "0" << endl;
}
else {
cout << max << endl;
}
return 0;
}
第三题:分数拆分
int main()
{
int k;
cin >> k;
int ans = 0;
int y, x;
for (y = k + 1; y <= 2 * k; y++)
{
x = k*y / (y - k);
if (k * y %(y - k)==0)//保证是个整数
{
++ans;
cout<<ans<<endl;
printf("1/%d=1/%d+1/%d\n", k, x, y);
}
}
return 0;
}
二.枚举排列
1.递归法生成排列
#include<iostream>
#include<cstdio>
using namespace std;
int ans=0;
void meiju(int n, int* a, int cur)
{
if (cur == n)
{
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}++ans;
printf("\n");
}
else
{
for (int i = 1; i <= n; i++)
{
int ok = 1;
for (int j = 0; j < cur; j++)
{
if (a[j] == i)ok = 0;
}
if (ok) {
a[cur] = i;
meiju(n, a, cur + 1);
}
}
}
}
int main()
{
int n; cin >> n;
int a[20];
int cur=0;
meiju(n, a, cur);
cout << ans << endl;
return 0;
}
2.下一个排列,用stl中的库函数
#include <algorithm>
void jiedashu()
{
int n;
cin >> n;
int aa[200];
for (int i = 0; i < n; i++)
{
cin >> aa[i];//3 2 1
}
sort(aa, aa + n);//1 2 3
do {
for (int j = 0; j < n; j++)//3
{
printf("%d ", aa[j]);
}
cout << "\n";
} while (next_permutation(aa, aa + n));//求下一个排列
}
int main()
{
jiedashu();
return 0;
}
三.枚举排列总结:
枚举排列的常见方法有两种,一种是递归枚举,一种是STL中的next_permutation函数;
四.回溯法
1.定义:当把问题分成若干步骤求解时候,如果当前步骤没有合法选择,则将函数返回上一级调用。
1.八皇后
题目大意:8*8的网格,有八个皇后,他们不能处于同一行同一列和对角线上,问共有几种排列方法;
//八皇后
#include<cstdio>
#include <iostream>
using namespace std;
int tot = 0; int n; int aa[100];
void search(int cur)
{
if (cur == n) tot++;
else for (int i = 0; i < n; i++){
int ok = 1;
aa[cur] = i;//第cur行皇后放入第i列
for (int j = 0; j < cur; j++)//检查和前面的皇后是否冲突
{
if(aa[cur]==aa[j]||cur-aa[cur]==j-aa[j]||cur+aa[cur]==j+aa[j])//判断列,主对角线和副对角线
{
ok = 0; break;
}
}
if (ok)search(cur + 1);
}
}
int main()
{
cin >> n;
search(0); cout << tot << endl;
}
2.素数环
题目:输入正整数n,把整数1,2,3....,n组成一个环,使得相邻的两个数之和均为素数,输出的时候从整数1开始逆时针排列,同一个环应恰好输出一次。n<=16。
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
int cur; int n; int aa[100]; bool book[20]; int ans = 1;
bool isp(int x)
{
if (x < 2)return false;
if (x ==2) return true;
for (int i = 2; i <= sqrt(x); i++)
{
if (x % i == 0)return false;
}
return true;
}
void dfs(int x)
{
if (x == n && isp(aa[0] + aa[n - 1]))
{
for (int i = 0; i < n - 1; i++)
{
cout<<aa[i]<<" ";
}
cout<<aa[n-1]<<endl;
return;
}
for (int i = 2; i <= n; i++)
{
if (!book[i] && isp(i + aa[x - 1]))
{
aa[x] = i;
book[i] = 1;
dfs(x + 1);
book[i] = 0;
}
}
}
int main()
{
while (cin >> n)
{
if (ans > 1)cout << endl;
cout << "Case " << ans << ":" << endl; ans++;
book[1] = 1; aa[0] = 1;
dfs(1);
memset(book, false, sizeof(book));
}
return 0;
}
作者:Better又
出处:https://www.cnblogs.com/lwyy1223-/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。