題意:
給你n,代表有0 n-1個人,給你n行,每行n個字符,
字符是X,i=j就是這個人在這個位置
1 代表,i人能贏j人當king
0代表輸;
遊戲規則是b 是king a能贏b a當king
問裁判按什麼安排順序0能當king
一開始思路是A能打贏B就連A到B,然後看能否從0遍歷到最後的n-1。比賽時考慮到數據量是1000,dfs最壞的複雜度是1000!。就放棄了,而我在想着如何剪枝,以失敗告終。
其實這題一開始就忽略了題意是說如何安排順序使得0能最終獲勝,而不是前一個人必須被後一個人打敗(這個就是我的想法),直到0打敗倒數第二個!可以說,我之前那樣想的是“如何安排順序使得0能最終獲勝”的特殊情況!找到特殊情況可不容易啊!所以超時是妥妥的……
總結:
dfs遍歷複雜時,可看看題意是否把握好。比如這題,“如何安排順序使得0能最終獲勝”,加入順序爲k1 k2 k3 k4……k1到k2可不是k1指向k2哦!還可以是k2指向k1.(k2 來挑戰k1,只不過失敗了而已)
#include <bits/stdc++.h>
using namespace std;
int n;
int a[1010][1010];
int used[1010];
int ans[1010];
char str[1010];
bool f;
int t;
void dfs(int u)
{
if(t==n-1)
{
f=1;
return ;
}
for(int i=0; i<n; i++)
if(a[u][i] && !used[i])
{
used[i]=1;
ans[t++]=i;
dfs(i);
}
return ;
}
int main()
{
cin>>n;
f=0,t=0;
memset(used,0,sizeof used);
for(int i=0; i<n; i++)
{
scanf("%s",str);
for(int j=0; j<n; j++)
{
if(str[j]=='X') a[i][j]=0;
else if(str[j]=='1') a[i][j]=1;
else a[i][j]=0;
}
}
used[0]=1;
dfs(0);
if(f)
{
for(int i=t-1; i>=0; i--) cout<<ans[i]<<' ';
cout<<0<<endl;
}
else
cout<<"impossible"<<endl;
return 0;
}