目录
目录
7、P1596 [USACO10OCT]Lake Counting S
一、递归
1、92.递归实现指数型枚举
总体思路:
递归终止:u > n 证明一层结束
开辟一个数组记录每一层递归每个数字使用过没有
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n;
const int N = 16;
bool use[N];
void bfs(int u) {
if (u > n){
for (int i = 1 ;i <= n; i++)
if(!use[i])
cout << i << " " ;
cout << endl;
return ;
}
use[u] = true; // 选这个数字
bfs(u + 1);
use[u] = false; // 还原
use[u] = false; // 不选这个数字
bfs(u + 1);
use[u] = false; // 还原
}
int main() {
cin >> n;
bfs(1);
return 0;
}
2 、94.递归实现排列形枚举
#include<iostream>
#include<cstdio>
const int N = 20;
bool use[N];
int state[N];
int n;
using namespace std;
void bfs(int u) {
// 停止条件
if (u > n) {
for (int i = 1; i <= n; i++)
cout << state[i] << " " ;
cout << endl;
return ;
}
// 从这里开始枚举
for (int i = 1; i <= n; i++) {
if(!use[i]) {
state[u] = i;
use[i] = true;
bfs(u + 1);
// 还原
state[u] = 0;
use[i] = false;
}
}
}
int main() {
cin >> n;
bfs(1);
return 0;
}
3、93.递归实现组合型枚举
#include<cstring>
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
int n,m;
vector<int> state(n);
vector<bool> use (m);
void dfs(int u) {
if(u == m) {
for(int i = 0; i < m; i++)
printf("%d ",state[i]);
cout << endl;
}
for(int i = 1; i <= m; i++) {
if(!use[i]) {
state[i] = i;
use[i] = true;
dfs(u + 1);
state[u] = 0;
use[i] = false;
}
}
}
int main() {
cin >> n;
cin >> m;
dfs(1);
return 0;
}
6、717.简单斐波那契
#include<cstdio>
#include<cstring>
#include<vector>
#include<iostream>
using namespace std;
int main()
{
int n;
cin >> n;
vector<int> f(n);
f[0] = 0;
f[1] = 1;
f[2] = 1;
for(int i = 3; i < n; i ++) {
f[i] = f[i - 1] + f[i - 2];
}
for(int i = 0; i < n; i ++) {
cout << f[i] << " ";
}
return 0;
}
7、1208.翻硬币
#include<cstdio>
#include<string>
#include<iostream>
using namespace std;
string startstr;
string endstr;
void change(int t) {
if(startstr[t] == '*')
startstr[t] = 'o';
else
startstr[t] = '*';
}
int main() {
cin >> startstr;
cin >> endstr;
int cnt = 0;
for(int i = 0 ;i < startstr.size() - 1; i ++){
if(startstr[i] != endstr[i]) {
cnt ++;
change(i);
change(i + 1);
}
}
cout << cnt;
return 0;
}
9、母牛的故事
思路:最主要的是递推表达式
#include<iostream>
using namespace std;
int cow[56] = {0,1,2,3,4};
int process(int n) {
for (int i = 4;i < 55; i++) {
cow[i] = cow[i - 1] + cow[i - 3];
}
return cow[n];
}
int main()
{
int n;
while ( cin >> n && n != 0) {
cout << process(n) << endl;
}
return 0;
}
10、放苹果
#include<iostream>
#include<cstdio>
using namespace std;
int process(int m ,int n){
//f(n,m) = 有盘子 + 没有空盘子;
if( m == 0 || n == 1){
return 1;
}
if(m < n) process(m,m);
else return process(m,n-1) + process(m - n,n); // ;有一个盘子里没有苹果,所有盘子里都有苹果
}
int main()
{
int t;
cin >>t;
while(t--){
int n,m;
cin >>m >>n;
cout << process(m,n) <<endl;
}
return 0;
}
13、821.跳台阶
#include <bits/stdc++.h>
using namespace std;
int n;
int dg(int dep)
{
if (dep == 1) return 1;
if (dep == 2) return 2; //终止条件
return dg(dep - 1) + dg(dep - 2);
}
int main()
{
scanf("%d", &n);
printf("%d\n", dg(n)); //用递归
return 0;
}
14、P1036 选数
#include<iostream>
using namespace std;
int n,k;
const int N = 26;
int a[N];
int state[N];
int cnt = 0;
bool isprime(int num) {
if (num < 2) {
return false;
}
for (int i = 2; i <= num / i; i ++) {
if (num % i == 0)
return false;
}
return true;
}
void dfs(int x, int start) { // x表示位置,start表示从几开始枚举
if ((x - 1) + n - start + 1 < k) // 剪枝
return ;
if (x > k) {
long long sum = 0;
for (int i = 1; i <= k; i++) {
sum += state[i];
}
if(isprime(sum)) {
cnt ++;
}
return ;
}
for (int i = start; i <= n; i++) {
state[x] = a[i];
dfs(x + 1,i + 1);
state[x] = 0;
}
}
int main() {
cin >> n >> k;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
}
dfs(1,1);
cout << cnt << endl;
return 0;
}
二、DFS
1、P2089 烤鸡
#include<iostream>
#include<algorithm>
#include<cstdio>
// 指数型枚举
// 依次枚举每个调料可以放几克
int n;
int k = 10;
const int N = 20;
int state[N];
int mem[59055][N];
int cnt = 0;
using namespace std;
void dfs(int x, int sum) {
if (sum > n) return;
if (x > k) {
if (sum == n) {
cnt ++;
for (int i = 1; i <= n; i++)
mem[cnt][i] = state[i];
}
return ;
}
for (int i = 1;i <= 3; i++) {
state[x] = i;
dfs(x + 1,sum + i);
state[x] = 0;
}
}
int main() {
cin >> n;
dfs(1,0);
cout << cnt << endl;
for (int i = 1; i <= cnt; i++){
for (int j = 1; j <= k; j++) {
cout << mem[i][j] << " ";
}
cout << endl;
}
return 0;
}
2、P1088.火星人
#include<iostream>
#include<cstdio>
const int N = 10010;
int arr[N];
int mars[N];
bool use[N];
int n, m;
int res = 0;
bool return0 = false;
using namespace std;
void dfs(int x) {
if (return0)
return;
if (x > n) {
res++;
if (res == m + 1) {
return0 = true;
for (int i = 1; i <= n; i++) {
cout << arr[i] << " ";
}
}
return;
}
for (int i = 1; i <= n; i++) {
if (!res)
i = mars[x];
if (!use[i]) {
use[i] = true;
arr[x] = i;
dfs(x + 1);
use[i] = false;
arr[x] = 0;
}
}
}
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i++) {
cin >> mars[i];
}
dfs(1);
return 0;
}
3、P1149 火柴棒
#include<iostream>
using namespace std;
int res = 0;
int n;
int nums[10010] = {6,2,5,5,4,5,6,3,7,6};
const int N = 10010;
int arr[N];
// 火柴棒数量
int col(int x) {
if (nums[x] > 0) return nums[x];
else {
int sumfire = 0;
while (x) {
sumfire += nums[x % 10];
x = x / 10;
}
return sumfire;
}
}
void dfs(int x,int sum) {
if (sum > n) return ;
if (x > 3) {
if (arr[1] + arr[2] == arr[3] && sum == n) {
res ++;
}
return ;
}
for (int i = 0; i <= 1000; i++) {
arr[x] = i;
dfs(x + 1,sum + nums[i]);
arr[x] = 0;
}
}
int main() {
cin >> n;
n = n - 4;
for (int i = 10; i <= 1000; i++) {
nums[i] = nums[i % 10] + nums[i / 10];
}
dfs(1,0);
cout << res << endl;
return 0;
}
4、P2036 PERKET
#include<iostream>
#include<cstdio>
int n;
int salt[20];
int bit[20];
int st[20];
using namespace std;
int res = 1e9;
void dfs(int x) {
if (x > n) {
bool has_tl = false;
int sum1 = 1;
int sum2 = 0;
for (int i = 1; i <= n; i ++) {
if (st[i] == 1) {
has_tl = true;
sum1 *= salt[i];
sum2 += bit[i];
}
}
if (has_tl) {
res = min(res,abs(sum1 - sum2));
}
return;
}
st[x] = 1;
dfs(x + 1);
st[x] = 0;
st[x] = 2;
dfs(x + 1);
st[x] = 0;
}
int main() {
cin >> n;
for (int i = 1; i <= n; i ++) {
cin >> salt[i];
cin >> bit[i];
}
dfs(1);
cout << res<< endl;
return 0;
}
5、P1135 奇怪的电梯
#include<iostream>
using namespace std;
int n,a,b;
int d[10010];
int res = 1e9;
bool st[10010];
void dfs(int x,int cnt) {
if (cnt >= res) return;
if (x < 0 || x > n) return;
if (x == b) {
res = min(res,cnt);
return ;
}
if (x + d[x] <= n && !st[x + d[x]]) {
st[x + d[x]] = true;
dfs(x + d[x],cnt + 1);
st[x + d[x]] = false;
}
if (x - d[x] > 0 && !st[x - d[x]]) {
st[x - d[x]] = true;
dfs(x - d[x],cnt + 1);
st[x - d[x]] = false;
}
}
int main() {
cin >> n >> a >> b;
for (int i = 1; i <= n; i ++) {
cin >> d[i];
}
dfs(a,0);
if (res == 1e9) {
cout << "-1" << endl;
return 0;
}
cout << res << endl;
return 0;
}
6、 P1683 入门
#include<iostream>
using namespace std;
const int N = 30;
char map[N][N];
int dx[4] = { -1,0,1,0 };
int dy[4] = { 0,1,0,-1 };
int m, n;
bool st[N][N];
int res = 0;
void dfs(int x, int y) {
for (int i = 0; i < 4; i++) {
int a = x + dx[i];
int b = y + dy[i];
if (a < 0 || a >= n || b < 0 || b >= m) continue;
if (map[a][b] != '.') continue;
if (st[a][b]) continue;
st[a][b] = true;
res++;
dfs(a, b);
}
}
int main() {
cin >> m >> n;
for (int i = 0; i < n; i++) {
cin >> map[i];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j] == '@') {
st[i][j] = true;
dfs(i, j);
}
}
}
res++;
cout << res << endl;
return 0;
}
7、P1596 [USACO10OCT]Lake Counting S
#include<iostream>
using namespace std;
int n, m;
const int N = 110;
char gap[N][N];
bool st[N][N];
int dx[] = { 1,1,1,0,0,-1,-1,-1 };
int dy[] = { -1,0,1,1,-1,1,0,-1 };
int res = 0;
void dfs(int x, int y) {
for (int i = 0; i < 8; i++) {
int a = x + dx[i];
int b = y + dy[i];
if (a < 0 || a >= n || b < 0 || b >= m) continue;
if (gap[a][b] == '.') continue;
if (st[a][b]) continue;
st[a][b] = true;
dfs(a, b);
}
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; i++) {
cin >> gap[i];
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (gap[i][j] == 'W' && !st[i][j]) {
dfs(i, j);
res++;
}
}
}
cout << res << endl;
return 0;
}
8、4408. 李白打酒加强版
#include<iostream>
#include<bits/stdc++.h>
using namespace std;
#define mod 1000000007
typedef long long LL;
const int N = 110;
LL n, m, ans, len;
LL res[N]; //用来记录李白路过花和店的序列
void dfs(int i,LL k,LL a,LL b) {
if (a > m || b > n)
return ;
if (i == len - 1 ) {
if (k == 1 && a == m - 1 && b == n) {
ans ++;
}
return ;
}
if (k <= 0) return;
dfs(i + 1,k - 1,a + 1,b);
dfs(i + 1,k + k, a, b + 1);
}
int main() {
cin >> n >> m;
len = n + m;
dfs(0, 2, 0, 0);
ans = ans % mod;
cout << ans;
return 0;
}
9、 P1101 单词方阵
#include<iostream>
using namespace std;
const int N = 110;
int n;
char map[N][N];
char ans[N][N];
char mark[N][N];
const string cmp = "yizhong"; // 比较数组
int dx[] = {1, 1, 1, 0, 0, -1,-1,-1};
int dy[] = {1, 0, -1,1, -1, 0, 1, -1};
void dfs(int x,int y) {
for (int i = 0; i < 8; i ++) {
int flag = 1;
for (int j = 1; j <= 6; j++) {
int nx = x + j * dx[i];
int ny = y + j * dy[i];
if(nx < 1 || nx > n || ny < 1 || ny > n) { //判越界
flag = 0;
break;
}
if (cmp[j] != map[nx][ny]) {
flag = 0;
break;
}
}
if (flag == 0)
continue;
for (int j = 0; j <= 6; j++) {
int nx = x + j * dx[i];
int ny = y + j * dy[i];
ans[nx][ny] = map[nx][ny];
}
}
return ;
}
int main () {
cin >> n;
for(int i = 1;i <= n;i++) {
for(int j = 1;j <= n;j++) {
cin >> map[i][j];
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++ ){
if (map[i][j] == 'y')
dfs(i,j);
}
}
for(int i = 1; i <= n; i++) { //输出
for(int j = 1; j <= n;j ++) {
if (ans[i][j] == 0) ans[i][j] = '*';//如果没有改动就输出*
cout << ans[i][j];
}
cout << endl;
}
return 0;
}