题意:给六个字符串每个字符串选一个字母组成“harbin”
思路:当时看到这题时我第一感觉是dfs,队友cg因为刚刚学过匈牙利匹配大喊这是匈牙利匹配,好像还吓到了隔壁桌的朋友,不过在cg再抄了许久板子之后发现板子有问题。。。最后还是用dfs过的。补题时也是用dfs写,但是发现如果剪枝不彻底会T,如今在学了匈牙利匹配后(发现其实不是很难的算法),又用匈牙利匹配a了一发,理论上匈牙利复杂度最坏6^3,dfs最坏6!,最后两种算法时间也差不多。我在下面把两种写法都贴出来
匈牙利写法
#include <bits/stdc++.h>
#define x first
#define y second
#define mid (l + r >> 1)
#define lo (o << 1)
#define ro (lo | 1)
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int, int> pii;
typedef vector<int> vi;
const int maxn = 1e5 + 10;
const int inf = 0x3f3f3f3f;
const ll linf = 0x3f3f3f3f3f3f3f3f;
const ll mod = 998244353;
struct tri{int x,y,z;};
string harbin="harbin";
bool edg[6][6],vis[6];
int linker[6];
bool dfs(int u)
{
for(int v=0;v<6;v++)if(edg[u][v]&&!vis[v])
{
vis[v]=1;
if(linker[v]==-1||dfs(linker[v]))
{
linker[v]=u;
return 1;
}
}
return 0;
}
bool solve()
{
memset(edg,0,sizeof(edg));
memset(linker,-1,sizeof(linker));
for(int i=0;i<6;i++)
{
string s;cin>>s;
for(auto j:s)for(int k=0;k<6;k++)
if(j==harbin[k])edg[i][k]=1;
}//建图
int ans=0;
for(int i=0;i<6;i++)
{
memset(vis,0,sizeof(vis));
if(dfs(i))ans++;
}
return ans==6;
}
int main()
{
// freopen("in.txt","r",stdin);
int _;cin>>_;
while(_--)
{
if(solve())puts("Yes");
else puts("No");
}
return 0;
}
DFS写法
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef float ld;
const int maxn=1e5+10;
const int inf=0x3f3f3f3f;
const char harbin[10]={"harbin"};
int boa[6][6],vis[6];
bool dfs(int step)
{
if(step==6)return 1;
for(int i=0;i<6;i++)
{
if(boa[step][i]&&vis[i]==0)
{
vis[i]=1;
if(dfs(step+1))
{
return 1;
}
vis[i]=0;
}
}
return 0;
}
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
memset(boa,0,sizeof(boa));
memset(vis,0,sizeof(vis));
string s[6];
for(int i=0;i<6;i++)
cin>>s[i];
for(int i=0;i<6;i++)
{
for(int j=0;j<s[i].length();j++)
{
for(int k=0;k<6;k++)
{
if(harbin[k]==s[i][j])boa[i][k]=1;
}
}
}
if(dfs(0))puts("Yes");
else puts("No");
}
return 0;
}