例题1:
附C++代码:
//
// 1458.cpp
// 汉诺塔III
//
// Created by chenmeiqi on 2019/4/12.
// Copyright © 2019年 chenmeiqi. All rights reserved.
//
#include <iostream>
using namespace std;
long long F(int x){ // 递归函数。返回值较大用 long long 类型
if(x==1){ // 参数为1时直接返回2
return 2;
}
else{
return 3*F(x-1)+2; // 否则递归调用
}
}
int main(int argc, const char * argv[]) {
int n;
while (cin>>n){
cout << F(n) <<endl;
}
return 0;
}
例题2
//
// 1459.cpp
// Prime ring problem
//
// Created by chenmeiqi on 2019/4/12.
// Copyright © 2019年 chenmeiqi. All rights reserved.
//
#include <iostream>
using namespace std;
int n;
int ans[17]; // 保存环中每一个被放入的数
bool mark[17]; // 标记之前已经被放入环中的数
bool isPrime(int x){ // 判断一个数是否是素数
for(int i=2;i<x;i++){
if(x%i==0){
return false;
}
}
return true;
}
void check(){
if(isPrime(ans[n]+ans[1])==false){ // 判断最后一个数与第一个数的和是否为素数,若不是则直接返回
return;
}
for(int i=1;i<=n;i++){ // 输出解,注意最后一个数字没有空格
if(i==1){
cout<<ans[i];
}
else{
cout<<" "<<ans[i];
}
}
cout<<endl;
}
void DFS(int x){ // 递归枚举,num为当前已经放入环中的数字
if(x>1){ // 当放入的数字大于 1 个时
if(isPrime(ans[x]+ans[x-1])==false){ // 判断最后两个数字的和是否为素数,若不是则返回继续枚举第num个数
return;
}
}
if(x==n){ // 若已经放入了n个数
check(); // 检查输出
return; // 返回,继续枚举下一组解
}
for(int i=2;i<=n;i++){ // 放入一个数
if(mark[i]==false){ // 若i还没有被放入环中
mark[i]=true; // 标记i为已经使用
ans[x+1]=i; // 将这个数字放入ans数组中
DFS(x+1); // 继续尝试放入下一个数
mark[i]=false; // 当回溯枚举这位数字时,将i重新标记为未使用
}
}
}
int main(int argc, const char * argv[]) {
int count=0; // 标记Case数
while (cin>>n){
count++; // Case数递增
cout<<"Case "<<count<<":"<<endl;
for(int i=0;i<17;i++){ // 初始化标记所有数字为未被使用
mark[i]=false;
}
ans[1]=1; // 第一个数字恒定为1
mark[1]=true; // 标记1被使用
DFS(1); // 继续尝试放入下一个数字
cout<<endl;
}
return 0;
}
例题3:
附C++代码:
//
// main.cpp
// Deposit
//
// Created by chenmeiqi on 2019/4/15.
// Copyright © 2019年 chenmeiqi. All rights reserved.
//
#include <iostream>
using namespace std;
char pos[100][100];
bool mark[100][100];
int go[][2]={
0,1,
0,-1,
1,0,
1,1,
1,-1,
-1,0,
-1,1,
-1,-1
};
int m,n;
void DFS(int x,int y){
int nx,ny;
for(int i = 0; i < 8; i++)
{
nx=x+go[i][0];
ny=y+go[i][1];
if(nx<0||nx>n||ny<0||ny>m){
continue;
}
if(pos[nx][ny]=='*'){
continue;
}
if(mark[nx][ny]==true){
continue;
}
mark[nx][ny]=true;
DFS(nx,ny);
}
return;
}
int main(int argc, const char * argv[]) {
int count;
while(cin>>m>>n){
count=0;
if(m==0){
break;
}
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
cin>>pos[i][j];
mark[i][j]=false;
}
}
for(int i=0;i<m;i++){
for(int j=0;j<n;j++){
if(pos[i][j]=='@'&&mark[i][j]==false){
DFS(i,j);
count++;
}
}
}
cout<<count<<endl;
}
}
v
例题4:
代码:
//
// 1461.cpp
// Temple of the bone
//
// Created by chenmeiqi on 2019/4/16.
// Copyright © 2019年 chenmeiqi. All rights reserved.
//
#include <iostream>
using namespace std;
char maze[7][7]; // 保存地图信息
int n,m,t; // 地图大小为n*m,从起点到终点能否恰好t秒
int go[][2]={ // 四个方向行走坐标差
1,0,
-1,0,
0,1,
0,-1
};
bool flag; // 是否成功
void DFS(int x,int y,int res_t){ // 递归形式的深度优先搜索
int nx,ny;
for(int i=0;i<4;i++){ // 枚举四个相邻位置
nx=x+go[i][0];
ny=y+go[i][1]; // 计算其坐标
if(nx<0||nx>=n||ny<0||ny>=m){ // 坐标在地图外
continue;
}
if (maze[nx][ny]=='X') { // 该位置为墙
continue;
}
if(maze[nx][ny]=='D'){ // 该位置为门
if(res_t+1==t){ // 所用时间恰好为t
flag=true; // 搜索成功
return; // 返回
}
else{ // 否则该状态的后续状态不可能为答案(经过的点不能再经过)
continue;
}
}
maze[nx][ny]='X'; // 该状态扩展而来的后续状态中,该位置都不能被经过,直接修改该位置为墙
DFS(nx,ny,res_t+1); // 递归z扩展该状态,所用时间递增
maze[nx][ny]='.'; // 若其后续状态全部遍历完毕,则退回上层状态,将因为要搜索其后续状态而改成墙的位置,改回普通位置
if (flag) { // 假如已经成功,则直接返回,停止搜索
return;
}
}
}
int main(int argc, const char * argv[]) {
int sx,sy;
int dx,dy;
string s;
while(cin>>n>>m>>t){
if(n==0&&m==0&&t==0){
break;
}
for(int i = 0; i < n; i++)
{
cin>>s;
for(int j = 0; j < m; j++)
{
maze[i][j]=s[j];
if(maze[i][j]=='S'){ // 找到起点位置
sx=i;
sy=j;
}
if(maze[i][j]=='D'){ // 找到终点位置
dx=i;
dy=j;
}
}
}
flag=false;
if (((sx+sy)%2+t%2)%2 == (dx+dy)%2 ) { // 判断S与D的奇偶关系是否与t符合,若不符合直接跳过搜索
maze[sx][sy]='X'; // 将起点标记为墙
DFS(sx,sy,0); // 递归扩展初始状态
}
if(flag){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
return 0;
}
另附此题的堆栈解法:
//
// 1461.cpp
// Temple of the bone 2
//
// Created by chenmeiqi on 2019/4/16.
// Copyright © 2019年 chenmeiqi. All rights reserved.
//
#include <iostream>
#include <stack>
using namespace std;
struct N{
int x;
int y;
int t;
};
stack<N> S;
int go[][2]={
1,0,
-1,0,
0,1,
0,-1,
};
char maze[7][7];
int n,m,t;
bool flag;
void DFS(){
int nx,ny;
while (!S.empty()) {
N now=S.top();
S.pop();
for (int i=0; i<4; i++) {
nx=now.x+go[i][0];
ny=now.y+go[i][1];
if (nx<0||nx>=n||ny<0||ny>=m) {
continue;
}
if (maze[nx][ny]=='X') {
continue;
}
if (maze[nx][ny]=='D' && now.t+1==t) {
flag=true;
return;
}
maze[nx][ny]='X';
N tmp;
tmp.x=nx;
tmp.y=ny;
tmp.t=now.t+1;
S.push(tmp);
}
}
};
int main(int argc, const char * argv[]) {
string s;
int sx,sy;
int dx,dy;
while (cin>>n>>m>>t) {
flag=false;
if (n==0 && m==0 && t==0) {
break;
}
for (int i=0; i<n; i++) {
cin>>s;
for (int j=0; j<m; j++) {
maze[i][j]=s[j];
if (s[j]=='S') {
sx=i;
sy=j;
}
if(s[j]=='D'){
dx=i;
dy=j;
}
}
}
while (!S.empty()) {
S.pop();
}
maze[sx][sy]='X';
N begin;
begin.x=sx;
begin.y=sy;
begin.t=0;
S.push(begin);
if(((sx+sy)%2 + t%2)%2 ==(dx+dy)%2){
DFS();
}
if(flag){
cout<<"YES"<<endl;
}
else{
cout<<"NO"<<endl;
}
}
return 0;
}