SET Transaction ISOlation Level Read xxx 語法的四種情況
搜尋
目錄1317 【例5.2】組合的輸出
【題目描述】
排列與組合是常用的數學方法,其中組合就是從 n 個元素中抽出 r 個元素(不分順序且 r ≤n),
我們可以簡單地將 n 個元素理解為自然數 1,2,…,n,從中任取 r 個數。
現要求你用遞迴的方法輸出所有組合。
【輸入】一行兩個自然數 n、r(1<n<21,1≤r≤n)。
【輸出】所有的組合,每一個組合佔一行且其中的元素按由小到大的順序排列,
每個元素佔三個字元的位置,所有的組合也按字典順序。
【輸入樣例】
5 3
【輸出樣例】
1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4
2 3 5
2 4 5
3 4 5
【參考程式】
#include<bits/stdc++.h> using namespace std; const int N=1e3; int a[N], vis[N], n, r; //第 m 個數 void dfs(int m){ if(m>r){ for(int i=1; i<=r; i++){ cout<<setw(3)<<a[i]; }cout<<endl; return; } for(int i=1; i<=n; i++){ if(vis[i]==0 && a[m-1]<i){ vis[i]=1; a[m] = i; dfs(m+1); vis[i] = 0; } } } int main(){ cin>>n>>r; dfs(1); return 0; }
1318 【例5.3】自然數的拆分
【題目描述】任何一個大於 1 的自然數 n,總可以拆分成若干個小於 n 的自然數之和。
【輸入】輸入n。
【輸出】按字典序輸出具體的方案。
【輸入樣例】
7
【輸出樣例】
7=1+1+1+1+1+1+1
7=1+1+1+1+1+2
7=1+1+1+1+3
7=1+1+1+2+2
7=1+1+1+4
7=1+1+2+3
7=1+1+5
7=1+2+2+2
7=1+2+4
7=1+3+3
7=1+6
7=2+2+3
7=2+5
7=3+4
【參考程式】
#include<bits/stdc++.h> using namespace std; int n,total=0; const int N=1e3; int a[N]; //現有和, 選擇第 m 個數 void dfs(int sum, int m) { if(sum>n) return; if(sum==n && m>2) { cout<<n<<"="; for(int i=1; i<m-1; i++) { cout<<a[i]<<"+"; } cout<<a[m-1]<<endl; return ; } for(int i=1; i<=n; i++) { if(sum+i<=n && a[m-1]<=i) { a[m] = i; dfs(sum+i, m+1); a[m] = 0; } } } int main() { cin>>n; dfs(0,1); return 0; }
1212 LETTERS
【題目描述】
給出一個 roe×col 的大寫字母矩陣,一開始的位置為左上角,
你可以向上下左右四個方向移動,並且不能移向曾經經過的字母。
問最多可以經過幾個字母。
【輸入】第一行,輸入字母矩陣行數 R 和列數 S,1≤R,S≤20。
接著輸出 R行 S列字母矩陣。
【輸出】最多能走過的不同字母的個數。
【輸入樣例】
3 6
HFDFFB
AJHGDH
DGAGEH
【輸出樣例】
6
【參考程式】
#include <bits/stdc++.h>
using namespace std;
char a[24][24];//這個用於儲存輸入的字元
bool po[30];//26個字母,用以判斷此字母是否被讀過了
int maxl;//儲存最大值
int pa[4] = { 1,0,-1,0 };//控制x走向
int pb[4] = { 0,1,0,-1 };//控制y走向
int n, m;
void f(int x1, int y1, int seft) { //x1代表此時橫座標,y1代表此時縱座標,seft代表 此時 不同字母的個數
if(seft>maxl) maxl=seft;//如果當前值大過最高值,則更新最高值
int x, y;
for (int i=0; i<=3; i++) {
//有四種方案,分別對應上下左右
x = x1+pa[i];
y = y1+pb[i];
//可行性方案,首先確保移動後的點在方格內,其次,這個點儲存的字母未被使用過
if (x>=1 && x<=n && y>=1 && y<=m && (!po[a[x][y]-'A'])) {
po[a[x][y]-'A'] = 1;//標記
f(x, y, seft+1);//遞迴
po[a[x][y]-'A'] = 0;//解除標記
}
}
}
int main() {
cin>>n>>m;
for (int i=1; i<=n; i++){
for (int j=1; j<=m; j++){
cin>>a[i][j];
}
}
po[a[1][1]-65] = 1;
f(1, 1, 1);//從第一個點開始即可
cout << maxl;
return 0;
}
1213 八皇后問題
【題目描述】在國際象棋棋盤上放置八個皇后,要求每兩個皇后之間不能直接吃掉對方。
【輸入】(無)
【輸出】按給定順序和格式輸出所有八皇后問題的解(見樣例)。
【輸入樣例】(無)
【輸出樣例】
No. 1
1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 0 1 0 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0
0 0 1 0 0 0 0 0
No. 2
1 0 0 0 0 0 0 0
0 0 0 0 0 0 1 0
0 0 0 1 0 0 0 0
0 0 0 0 0 1 0 0
0 0 0 0 0 0 0 1
0 1 0 0 0 0 0 0
0 0 0 0 1 0 0 0
0 0 1 0 0 0 0 0
...以下省略
【參考程式】
#include<bits/stdc++.h>
using namespace std;
const int N=1e3;
int a[N],b[N],c[N],d[N],n,cnt=0;
// a[j]=i; //第i行第j列放置
// b[j]=1; //第j列已經放置
// c[i+j]=1; //對角線(右上角到左下角)已放置
// d[i-j+n]=1;//對角線(左上角到右下角)已放置
// 每行/列一個皇后,也就是 第i行/列是第 i個皇后
//放置第 k 個皇后
void dfs(int i){
if(i>n){
cnt++;
cout<<"No. "<<cnt<<endl;
for(int k=1;k<=n; k++) {
for(int j=1; j<=n; j++){
if(a[k]==j) cout<<1<<" ";
else cout<<0<<" ";
}cout<<endl;
}
return ;
}
for(int j=1; j<=n; j++){
if(b[j]==0 && c[i+j]==0 && d[i-j+n]==0){
a[j]=i, b[j]=1, c[i+j]=1, d[i-j+n]=1;
dfs(i+1);
b[j]=0, c[i+j]=0, d[i-j+n]=0;
}
}
}
int main(){
n=8; //cin>>n;
dfs(1);
return 0;
}
1214:八皇后
【題目描述】
會下國際象棋的人都很清楚:皇后可以在橫、豎、斜線上不限步數地吃掉其他棋子。
如何將 8 個皇后放在棋盤上(有 8 ×8個方格),使它們誰也不能被吃掉!這就是著名的八皇后問題。
對於某個滿足要求的8皇后的擺放方法,定義一個皇后串 a 與之對應,即 a=b1b2...b8,
其中 bi 為相應擺法中第 i 行皇后所處的列數。
已經知道 8 皇后問題一共有 92 組解(即 92 個不同的皇后串)。
給出一個數 b,要求輸出第 b 個串。
串的比較是這樣的:皇后串 x 置於皇后串 y 之前,當且僅當將 x 視為整數時比 y 小。
【輸入】第 1 行是測試資料的組數n,後面跟著n行輸入。
每組測試資料佔1行,包括一個正整數b(1≤b≤92)。
【輸出】輸出有n行,每行輸出對應一個輸入。輸出應是一個正整數,是對應於b的皇后串。
【輸入樣例】
2
1
92
【輸出樣例】
15863724
84136275
【參考程式】
#include<bits/stdc++.h>
using namespace std;
const int N=1e3;
int a[N],b[N],c[N],d[N], n, cnt=0;
int data[N][N];
// a[j]=i; //第i行第j列放置
// b[j]=1; //第j列已經放置
// c[i+j]=1; //對角線(右上角到左下角)已放置
// d[i-j+n]=1;//對角線(左上角到右下角)已放置
// 每行/列一個皇后,也就是 第i行/列是第 i個皇后
//每一列一個皇后
void dfs(int j){
if(j>n){
cnt++;
for(int i=1; i<=n; i++){
data[cnt][i]=a[i];
}
}
for(int i=1; i<=n; i++){
if(b[i]==0 && c[i+j]==0 &&d[i-j+n]==0){
a[j]=i, b[i]=1, c[i+j]=1, d[i-j+n]=1;
dfs(j+1);
b[i]=0, c[i+j]=0, d[i-j+n]=0;
}
}
}
int main(){
n=8;
dfs(1);
int num; cin>>num;
for(int i=1; i<=num; i++){
int b; cin>>b;
for(int j=1; j<=n; j++){
cout<<data[b][j];
}cout<<endl;
}
return 0;
}
1215 迷宮
1216 紅與黑
1217 棋盤問題
1218 取石子游戲
1219 馬走日
【參考程式】
#include<iostream>
#include<cstring>
using namespace std;
const int N=10;
int a[N][N];
int dis[][2]={-2,-1, -1,-2, 1,-2, 2,-1, 2,1, 1,2, -1,2, -2,1};
int n,m,sx,sy,ans;
void pr(){
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
cout<<a[i][j]<<" ";
}cout<<endl;
}cout<<endl;
}
//遍歷數量,將要遍歷的點
void dfs(int cnt,int x,int y){
// if(cnt<4) pr();
if(cnt==n*m) {
ans++; return;
}
for(int i=0; i<8; i++){
int tx=x+dis[i][0];
int ty=y+dis[i][1];
if(tx<0||tx>=n||ty<0||ty>=m) continue;
if(a[tx][ty]==0){
a[tx][ty]=1;
dfs(cnt+1,tx,ty);
a[tx][ty]=0;
}
}
}
int main(){
// freopen("data.in", "r", stdin);
int t; cin>>t;
while(t--){
cin>>n>>m>>sx>>sy;
ans=0;
memset(a, 0, sizeof(a));
a[sx][sy]=1;
dfs(1,sx,sy);
cout<<ans<<endl;
}
return 0;
}