版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chengchencheng/article/details/82721599
1.数字全排列
输出N个数字的所有排列组合情况
#include<iostream>
using namespace std;
void search(int m);
void output();
int n;
int arr[10];
int main(){
cin >> n;
for(int i = 0; i < n; i++){
arr[i] = i+1;
}
search(0);
return 0;
}
void search(int m){
int tmp;
if(m == n){
output();
}
else{
//输出以第m个打头的所有组合
for(int i = m; i < n; i++){
tmp = arr[i]; //交换arr[i]与arr[m]
arr[i] = arr[m];
arr[m] = tmp;
search(m+1);
tmp = arr[i]; //将arr[i]与arr[m]交换回来
arr[i] = arr[m];
arr[m] = tmp;
}
}
}
void output(){
for(int i = 0; i < n; i++){
cout<<arr[i];
}
cout<<endl;
}
2.0-1背包
#include<iostream>
using namespace std;
int search(int m, int w);
void init();
int n, c;
struct bag{
int weight, value;
}num[100];
int main(){
init();
cout << search(n, c) << endl;
}
void init(){
cin >> n >> c;
for(int i = 0; i < n; i++){
cin >> num[i].weight;
}
for(int i = 0; i < n; i++){
cin >> num[i].value;
}
}
int search(int m,int w){
int i;
if(m == 0 || w == 0){
return 0;
}
else{
for(i = m-1; i >= 0; i--){
if(num[i].weight > w){ //当前背包不能容纳,则不放入
return search(m-1, w);
}
else{
int tmp1 = search(m-1, w); //不放入的价值
int tmp2 = num[i].value + search(m-1, w-num[i].weight); //放入后的价值
return(tmp1>tmp2 ? tmp1:tmp2);
}
}
}
}
智商不够,只能算出来最终结果,不能显示出最优解的具体情况。
3.迷宫问题
输入:先输入两个不超过20的正整数表示迷宫的行数m和列数n,再输入口和出口的坐标,最后分m行输入迷宫,其中1表示墙,0表示空格每个数字之间都有空格。
输出:只能向上、下、左、右四个方向走若能到达,则输出"Yes",否则输出"No",结果占一行。
输入样例:
3 3
0 0
2 2
0 0 0
1 1 0
0 1 0
输出样例:Yes
#include<iostream>
#include<queue>
using namespace std;
int m,n;
int gx, gy, tx, ty;
int arr[21][21];
int used[21][21];
int row[4] = {0, -1, 0, 1};
int col[4] = {1, 0, -1, 0};
struct{
queue<int> q1;
queue<int> q2;
}add;
int search(int x, int y);
int main(){
cin >> m >> n;
cin >> gx >> gy >> tx >> ty;
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
cin >> arr[i][j];
if(arr[i][j] == 1){
used[i][j] = 1;
}
else{
used[i][j] = 0;
}
}
}
used[gx][gy] = 1;
add.q1.push(gx);
add.q2.push(gy);
if(search(gx, gy)){
cout << "Yes" <<endl;
}
else{
cout << "No" << endl;
}
}
int search(int x, int y){
int e, f, nx, ny;
while(1){
if(add.q1.empty()){
return 0;
}
else{
e = add.q1.front();
add.q1.pop();
f = add.q2.front();
add.q2.pop();
for(int i = 0; i < 4; i++){
nx = e + row[i];
ny = f + col[i];
if(nx == tx && ny == ty){
return 1;
}
if(nx < 0 || nx >= m || ny < 0 || ny >=n) continue;
if(!used[nx][ny]){
used[nx][ny] = 1;
add.q1.push(nx);
add.q2.push(ny);
}
}
}
}
}
4.8皇后问题
描述:输出8皇后问题所有结果。
输入:没有输入。
输出:每个结果第一行是No n:的形式,n表示输出的是第几个结果;下面8行,每行8个字符,‘A’表示皇后,‘.’表示空格。不同的结果中,先输出第一个皇后位置靠前的结果;第一个皇后位置相同,先输出第二个皇后位置靠前的结果;依次类推。
输出样例:输出的前几行:
No 1:
A.......
....A...
.......A
.....A..
..A.....
......A.
.A......
...A....
No 2:
A.......
.....A..
.......A
..A.....
......A.
...A....
.A......
....A...
提示:输出样例是正确输出结果的前几行。
#include<iostream>
#include<string.h>
using namespace std;
void search(int m);
void output();
int cando(int row, int col);
int map[8];
int cnt;
int main(){
cnt = 1;
search(0);
return 0;
}
void search(int m){
if(m == 8){
output();
}
else{
for(int i = 0; i < 8; i++){
if(cando(m, i)){
map[m] = i;
search(m+1);
}
}
}
}
int cando(int row, int col){
int i;
for(i = 0; i < row; i++){
if(col == map[i] || (row-i == col-map[i]) || (row-i==map[i]-col)){
return 0;
}
}
return 1;
}
void output(){
int i, j;
cout << "No " << cnt++ << ":" <<endl;
for(i = 0; i < 8; i++){
for(j = 0; j < 8; j++){
if(map[i] == j){
cout << "A";
}
else{
cout << ".";
}
}
cout << endl;
}
}
5.又一个迷宫
描述:给一个20×20的迷宫、起点坐标和终点坐标,问从起点是否能到达终点。
输入:多个测例。输入的第一行是一个整数n,表示测例的个数。接下来是n个测例,每个测例占21行,第一行四个整数x1,y1,x2,y2是起止点的位置(坐标从零开始),(x1,y1)是起点,(x2,y2)是终点。下面20行每行20个字符,’.’表示空格;’X’表示墙。
输出:每个测例的输出占一行,输出Yes或No。
2
0 0 19 19
....................
XXXXXXXXXXXXXXXXXXXX
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
....................
0 0 19 19
....................
XXXXXXXXXXXXXXXXXXX.
....................
.XXXXXXXXXXXXXXXXXXX
....................
XXXXXXXXXXXXXXXXXXX.
....................
.XXXXXXXXXXXXXXXXXXX
....................
XXXXXXXXXXXXXXXXXXX.
....................
.XXXXXXXXXXXXXXXXXXX
....................
XXXXXXXXXXXXXXXXXXX.
XXXXXXXXXXXXXXXXXXX.
XXXXXXXXXXXXXXXXXXX.
XXXXXXXXXXXXXXXXXXX.
....................
.XXXXXXXXXXXXXXXXXXX
....................
输出样例:
No
Yes
#include<iostream>
#include<queue>
using namespace std;
int n;
int gx, gy, tx, ty;
char arr[20][20];
int used[20][20];
int row[4] = {0, -1, 0, 1};
int col[4] = {1, 0, -1, 0};
struct{
queue<int> q1;
queue<int> q2;
}add;
int search(int x, int y);
int main(){
cin >> n;
while(n--){
cin >> gx >> gy >> tx >> ty;
for(int i = 0; i < 20; i++){
for(int j = 0; j < 20; j++){
cin >> arr[i][j];
if(arr[i][j] == 'X'){
used[i][j] = 1;
}
else{
used[i][j] = 0;
}
}
}
used[gx][gy] = 1;
add.q1.push(gx);
add.q2.push(gy);
if(search(gx, gy)){
cout << "Yes" <<endl;
}
else{
cout << "No" << endl;
}
}
}
int search(int x, int y){
int e, f, nx, ny;
while(1){
if(add.q1.empty()){
return 0;
}
else{
e = add.q1.front();
add.q1.pop();
f = add.q2.front();
add.q2.pop();
for(int i = 0; i < 4; i++){
nx = e + row[i];
ny = f + col[i];
if(nx == tx && ny == ty){
return 1;
}
if(nx < 0 || nx >= 20 || ny < 0 || ny >=20) continue;
if(!used[nx][ny]){
used[nx][ny] = 1;
add.q1.push(nx);
add.q2.push(ny);
}
}
}
}
}
6.堡垒问题
描述:城堡是一个4×4的方格,为了保卫城堡,现需要在某些格子里修建一些堡垒。城堡中的某些格子是墙,其余格子都是空格,堡垒只能建在空格里,每个堡垒都可以向上下左右四个方向射击,如果两个堡垒在同一行或同一列,且中间没有墙相隔,则两个堡垒都会把对方打掉。问对于给定的一种状态,最多能够修建几个堡垒。
输入:每个测例以一个整数n(1<=n<=4)开始,表示城堡的大小。接下来是n行字符每行n个,‘X’表示该位置是墙,‘.’表示该位置是空格。n等于0标志输入结束。
输出:每个测例在单独的一行输出一个整数:最多修建堡垒的个数。
输入样例:
4
.X..
....
XX..
....
2
XX
.X
3
.X.
X.X
.X.
3
...
.XX
.XX
4
....
....
....
....
0
输出样例:
5
1
5
2
4
#include<iostream>
#include<string.h>
using namespace std;
void search(int m);
void output();
int cando(int t);
int min(int x, int y);
int max(int a, int b);
char tu[5][5];
int used[5][5];
int cnt;
int Max;
int n;
int main(){
while(cin >> n && n){
memset(tu, 0, sizeof(char));
memset(used, 0, sizeof(used));
for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++){
cin >> tu[i][j];
if(tu[i][j] == 'X'){
used[i][j] = 2;
}
}
}
cnt = 0;
Max = 0;
search(0);
cout << Max << endl;
}
}
void search(int m){
if(m == n*n){
if(Max < cnt){
Max = cnt;
}
}
else{
if(cando(m)){
for(int i = 0; i < 2; i++){
if(i == 0){
cnt++;
used[m/n][m%n] = 1;
search(m+1);
used[m/n][m%n] = 0;
cnt--;
}
else{
search(m+1);
}
}
}
search(m+1);
}
}
int cando(int t){
int i, j, row, col, flag;
row = t/n;
col = t%n;
if(used[row][col] == 1 || used[row][col] == 2){
return 0;
}
else{
/* flag = 1;
for(i = 0; i < n; i++){
if(used[row][i] == 1){
for(j = min(col, i)+1; j < max(col, i); j++){
if(used[row][j] == 2){
flag = 0;
break;
}
}
if(flag){
return 0;
}
else{
flag = 1;
}
}
if(used[i][col] == 1){
for(j = min(i, row)+1; j < max(i, row); j++){
if(used[i][col] == 2){
flag = 0;
break;
}
}
if(flag){
return 0;
}
else{
flag = 1;
}
}
}
return (flag);*/
if(row > 0){
for(i = row-1; i >=0; i--){
if(used[i][col] == 1){
return 0;
}
else if(used[i][col] == 2){
break;
}
}
}
if(row < n-1){
for(i = row+1; i < n; i++){
if(used[i][col] == 1){
return 0;
}
else if(used[i][col] == 2){
break;
}
}
}
if(col > 0){
for(i = col-1; i >=0; i--){
if(used[row][i] == 1){
return 0;
}
else{
break;
}
}
}
if(col < n-1){
for(i = col+1; i < n; i++){
if(used[row][i] == 1){
return 0;
}
else{
break;
}
}
}
return 1;
}
}
int min(int x, int y){
if(x < y){
return x;
}
else{
return y;
}
}
int max(int a, int b){
if(a > b){
return a;
}
else{
return b;
}
}
7.三阶幻方
描述:三阶幻方是最简单的幻方,又叫九宫格,是由1,2,3,4,5,6,7,8,9九个数字组成的一个三行三列的矩阵,其对角线、横行、纵向的的和都为15。
输入:无
输出:按字典序输出所有的满足条件的幻方矩阵,每两个数字之间带一个空格,行尾无空格,每个幻方后带一个空行。
输入样例:无
输出样例:无
#include<iostream>
#include<string.h>
using namespace std;
void search(int m);
void output();
void judge();
int used[10];
int map[3][3];
int main(){
memset(map, 0, sizeof(map));
memset(used, 0, sizeof(used));
search(0);
return 0;
}
void search(int m){
if(m == 9){
judge();
}
else{
for(int i = 1; i <=9; i++){
if(used[i] == 0){
map[m/3][m%3] = i;
used[i] = 1;
search(m+1);
used[i] = 0;
}
}
}
}
void judge(){
int i, j, flag = 1;
for(i = 0; i < 3; i++){
j = 0;
if(map[i][j] + map[i][j+1] + map[i][j+2] != 15){
flag = 0;
}
else if(map[j][i] + map[j+1][i] + map[j+2][i] != 15){
flag = 0;
}
}
if(map[0][0] + map[1][1] + map[2][2] != 15){
flag = 0;
}
if(map[0][2] + map[1][1] + map[2][0] != 15){
flag = 0;
}
if(flag){
output();
}
}
void output(){
int i, j;
j = 0;
for(i = 0; i < 3; i++){
cout <<map[i][j] <<" "<<map[i][j+1]<<" "<< map[i][j+2]<<endl;
}
cout <<endl;
}
8.图的m着色问题
描述:给定无向连通图G和m种不同的颜色。用这些颜色为图G的各顶点着色,每个顶点着一种颜色。如果有一种着色法使G中每条边的2个顶点着不同颜色,则称这个图是m可着色的。图的m着色问题是对于给定图G和m种颜色,找出所有不同的着色法。
输入:第1行有3个正整数n,r 和m(n < 20,r < 200,m < 10),表示给定的图G有n个顶点和r条边,m种颜色。顶点编号为0,1,2,…,n-1。接下来的k行中,每行有2个正整数u,v,表示图G 的一条边(u,v)。
输出:输出不同的着色方案的总数。
输入样例:
3 2 2
0 1
1 2
输出样例:2
#include<iostream>
#include<string.h>
using namespace std;
void search(int t);
int n, r, m;
int map[21][21];
int color[11];
int ans;
int main(){
int u, v;
memset(map, 0, sizeof(map));
memset(color, 0, sizeof(color));
cin >> n >> r >> m;
while(r--){
cin >> u >> v;
map[u][v] = map[v][u] = 1;
}
ans = 0;
search(0);
cout << ans << endl;
return 0;
}
void search(int t){
if(t == n){
ans++;
}
else{
for(int i = 0; i < m; i++){
int flag = 1;
for(int j = 0; j < t; j++){
if(map[t][j] && color[j] == i){
flag = 0;
break;
}
}
if(flag){
color[t] = i;
search(t+1);
}
}
}
}
9.字母转换
描述:通过栈交换字母顺序。给定两个字符串,要求所有的进栈和出栈序列(i表示进栈,o表示出栈),使得字符串2在求得的进出栈序列的操作下,变成字符串1。输出结果需满足字典序。例如TROT 到 TORT:
[
i i i i o o o o
i o i i o o i o
]
输入:给定两个字符串,第一个字符串是源字符串,第二个字符是目标目标字符串。
输出:所有的进栈和出栈序列,输出结果需满足字典序
输入样例:
madam
adamm
bahama
bahama
long
short
eric
rice
输出样例:
[
i i i i o o o i o o
i i i i o o o o i o
i i o i o i o i o o
i i o i o i o o i o
]
[
i o i i i o o i i o o o
i o i i i o o o i o i o
i o i o i o i i i o o o
i o i o i o i o i o i o
]
[
]
[
i i o i o i o o
]
#include<iostream>
#include<stack>
using namespace std;
void dfs(int m);
void output();
bool judge();
stack <char> s;
char s1[1000];
char s2[1000];
char step[1000], ans[1000];
int len1, len2;
int cnt_in, cnt_out;
int main(){
memset(s1, 0, sizeof(char));
memset(s2, 0, sizeof(char));
memset(step, 0 , sizeof(char));
memset(ans, 0 ,sizeof(char));
while(gets(s1) && s1!=NULL){
gets(s2);
cout << '[' << endl;
len1 = strlen(s1);
len2 = strlen(s2);
if(len1 == len2){
cnt_in = 0;
cnt_out = 0;
dfs(0);
}
cout << ']' << endl;
memset(s1, 0, sizeof(char));
memset(s2, 0, sizeof(char));
memset(step, 0 ,sizeof(char));
memset(ans, 0, sizeof(char));
}
}
void dfs(int m){
if(m == len1*2 && judge()){
output();
}
else{
if(cnt_in < len1){
cnt_in++;
step[m] = 'i';
dfs(m+1);
cnt_in--;
}
if(cnt_out < cnt_in){
cnt_out++;
step[m] = 'o';
dfs(m+1);
cnt_out--;
}
}
}
bool judge(){
int i, j, k;
j = 0; k = 0;
for(i = 0; i < len1*2; i++){
if(step[i] == 'i'){
s.push(s1[j++]);
}
else{
ans[k++] = s.top();
s.pop();
}
}
for(i = 0; i < len1; i++){
if(ans[i] != s2[i]){
return false;
}
}
return true;
}
void output(){
int i;
for(i = 0; i < len1*2-1; i++){
cout << step[i] << " ";
}
cout << step[i];
cout << endl;
}