問題の思考+ +個人記録への単純な検索ソリューション
- チェス盤
チェッカーボードにおいて片、個ない差の上方に配置さ(形状が不規則であってもよい)の形状を与えられ。任意の二枚の表示が要求される場合、同じ行またはボードにおいて同一列に配置することができない、所与の基板サイズ及び形状を解決するためのプログラムの要件は、すべての可能な配置スキームCのk個を配置すること
入力
データの複数のセットを含むテスト入力。
各データの最初の行は、スペースで区切られた2つの正の整数、NKを、であり、ボードの数はN * Nの行列に説明する表し、ピースを置きます。N <= 8、K <= N
の入力端が-1で表される場合-1。
その後、n行市松模様の形状について説明:N#は基板面積を表す行あたりの文字を、空白領域(余分な空白行のデータが表示されるか、空欄ないことが保証されている)を示しています。
出力
データの各セットに対して、出力の1本のラインを、出力表示プログラムCの数が与えられている(データはC ^ 31 <2を保証します)。
サンプル入力
2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1
サンプル出力
2
1
A DFSタイトル、各行の各列のみポーンを置くことができることを条件とレベル行列N k個のポーン、へ。前のレベルへの復帰は、検索を続行しないように場合したがって、我々は、可能なノードレベルの後の次の検索を見つけ、n階層ツリーとして、各行の各列を検索することができます。以下のコード+ノート。
#include<bits/stdc++.h>
using namespace std;
char mp[10][10];//绘制地图
int vis[10];//因为从每行搜,所以只需标记每列是否被访问
int r,c,n,k,sum;//行,列,矩阵大小,棋子个数,方案总和
void dfs(int r,int w){ //r表示搜索当前行,w表示为当前放棋子个数
if(w>=k)//终止条件,如果放完所有棋子,方案数+1
{
sum++;//!!!!!此处if(里面两个语句应该大括号,没输大括号导致WA
return;
}
for(int i=r;i<n;i++)
for(int j=0;j<n;j++)
{
if(!vis[j]&&mp[i][j]=='#')
{
vis[j]=1;//放置该棋子后该列标记
dfs(i+1,w+1);//!!!!此处应该是搜索i+1行,而不是r+1
vis[j]=0;//清楚标记,防止下次访问再放置该列
}
}
return;
}
int main(){
while(cin>>n>>k)
{
if(n==-1&&k==-1) break;
memset(vis,0,sizeof(vis));//每次输入一组数据就将其初始化
memset(mp,0,sizeof(mp));
for(int i=0;i<n;i++)
cin>>mp[i];
sum=0;
dfs(0,0);
cout<<sum<<endl;
}
return 0;
}
オイル回収B-
流出油の海上輸送の問題では、収益性の高い新しい産業が生まれて、そしてそれは、石油業界をスキミングされます。さて、メキシコ湾大規模な油浮きで、それは多くのビジネスマンの注目を集めました。これらのビジネスの人々は、あなたが20メートルを10メートルは、このような大きな長方形を取る全体注ぎ海をスキップすることができ、特別な平面を持っています。油は水を注いだがある場合、もちろん、これはすべての油過去スキムのスプーン必要(Upと隣接する又は隣接格子約ダウンは、ある角度で配置することができない)、それはリソースを活用することが完全にできない、無意味です。さて、トレーダーは、彼が油をすくうために立ち上がることができますどのくらい、この領域で、知りたいです。
マップは、各グリッドは、各領域の10メートル×10メートルの正方形領域を表し、N×Nのネットワークでは、油又は水に示されています
入力
試験データを複数含む試験入力
最初の行のテストデータT(T <75)のテストデータの数を与える
次のN、マップ領域の大きさを示すために、各試験サンプルについて、デジタルであるN(N <50)行、各行はN個の文字を有する、請求記号「」海を表し、記号『#』は、油を示します。
出力
出力フォーマット「ケースX:M」(X 1から始まる)、Mは、商人が油の中で最も量を得ることができます。
例1
エントリー
1
6
......
.##...
......
.#..#.
.#..##
......
輸出
Case 1: 3
A DFS +数学問題、Nレベルのマトリックス、最大の石油発見の確立は、2つの隣接する上下の座標を知ることは容易で、XY座標系と、燃料は、2点の座標が含まれているとされなければならないことを、偶数奇数のいずれかになります奇数-偶数点は、以下の図から知られており、油の奇数と偶数の最小値をとり
、次のコード
#include<bits/stdc++.h>
using namespace std;
char s[60][60];
int odd,even,n;
void dfs(int x,int y){
if (x>=n||y>=n||x<0||y<0||s[x][y]=='.') return;//越界或者无油则返回
(x+y)&1?++odd:++even;//如果x+y和为奇数则odd++,偶数even++;
s[x][y]='.';//标记
dfs(x+1,y);//四个方向搜索
dfs(x-1,y);
dfs(x,y+1);
dfs(x,y-1);
}
int main(){
int t,kase=0;
cin>>t;
while(t--){
scanf("%d",&n);
int ans=0;
for (int i=0; i<n; ++i) cin>>s[i];//绘图
for (int i=0; i<n; ++i)
for (int j=0; j<n; ++j)
if (s[i][j]=='#'){
odd=even=0;//每次都要初始化
dfs(i,j);
ans+=min(odd,even);
}
printf("Case %d: %d\n",++kase,ans);
}
}