原题链接:链接;
我的代码:
cpp
#include<iostream>
#include<vector>
using namespace std;
int m,x,y;
int cnt[5];
bool same[13][13];
int ret;
vector<int> path;
bool isSame(int pos,int cur){
for(int i = 1;i<pos;i++){
if(same[pos][i]&&cur!=path[i]){
return false;
}
}
return true;
}
void dfs(int pos){
if(pos>12){
ret++;
return;
}
for(int i = 1;i<=4;i++){
if(cnt[i]==0)continue;
if(!isSame(pos,i))continue;
cnt[i]--;
path.push_back(i);
dfs(pos+1);
cnt[i]++;
path.pop_back();
}
}
int main(){
for(int i = 1;i<=4;i++)cin>>cnt[i];
cin>>m;
while(m--){
cin>>x>>y;
same[x][y] = same[y][x] = true;
}
path.push_back(0);
dfs(1);
cout<<ret<<endl;
return 0;
}
需要注意的地方:
1.path.push_back(0);这是一个占位符,path是一个变长数组,里面记录着一轮dfs时,在12个选项上填写的答案。我们想让path[i]表示第i个位置填写的是哪个选项,从而做出是否符合要求的判断。所以path[0]没有意义,但是需要占位。
2.same[x][y] = same[y][x] = t;注意:x和y位置答案要一样,意味着y和x位置答案也要一样。
3.isSame函数用来判断,第pos位置填写cur是否符合题目中的m个条件中的x位置和y位置答案要一样,我们封装了这样的函数进行判断,有了path数组便可以详细记录是否满足它的要求。每一轮dfs完成后都会pop_back();所以path数组详细记录了一次dfs下去,12个选项中填写的答案。
4.cnt[5]数组中,cnt[i]代表在i 还有多少个,比如cnt[2]==5;表示B选项还有5个没有填写进去。
5.same[i][j]代表第i个题目和第j个题目的答案要一样。