[ABC326D] ABC Puzzle
思路
不难。
发现只有三个字母时果断状压,通过观察我们可以发现 \(n\) 和 \(m\) 都很小,然后我们就可以想到暴搜了,我们可以对于每一行一行的去填数,这里我们发现只需要是的满足题目给出的那两个串的条件即可。
这里我们定义 \(hang_i,lie_i\) 表示第 \(i\) 行和第 \(i\) 列的状态(二进制下第 \(i\) 位为一表示第 \(i\) 个大写字母已经选过了),然后我们就可以发现如果第 \(i\) 行已经到了最后一个我们就可以去判断一下这一行填的第 \(1\) 个数是否与要求填的第一个数相同,若相同则继续往后填,如果这一列还没有填数则将要填的数和想要填的数进行比较即可。
细节见代码。
代码
#include <bits/stdc++.h>
using namespace std ;
#define int long long
#define rep(i,x,y) for(int i=x;i<=y;i++)
#define rep1(i,x,y) for(int i=x;i>=y;i--)
#define fire signed
#define kong putchar(' ')
#define end putchar('\n')
#define in(x) scanf("%lld",&x)
#define lcm(x,y) x*y/__gcd(x,y)
#define il inline
il void print(int x) {
if(x>=10) print(x/10);
putchar(x%10+'0');
}
int n;
string s,t;
char c[10][10];
int lie[10],hang[10];
char nowx[10],nowy[10];
bool check(int x,int y,int i,int j,char c) { //判断是否匹配
if(x==0) if(c!=t[j]) return false;
if(y==0) if(c!=s[i]) return false;
return 1;
}
void dfs(int x,int y) {
if(x==n+1&&y==1) {
int f=0;
rep(i,1,n) if(lie[i]!=7||hang[i]!=7) return ; //判断每一行和每一列上是否都用到了三个字母
puts("Yes");
rep(i,1,n) {
rep(j,1,n) {
cout<<c[i][j];
}
cout<<endl;
}
exit(0);
}
rep(i,0,2) {
if((lie[y]&(1<<i))!=(1<<i)&&(hang[x]&(1<<i))!=(1<<i)&&check(lie[y],hang[x],x,y,i+'A')) {//判断是否冲突
int ip=1<<i;
lie[y]|=(1<<i);
hang[x]|=ip;
c[x][y]=(i+'A');
if((y+1)>n&&hang[x]==7) dfs(x+1,1); //跳到下一行第一个
else if(y+1<=n)dfs(x,y+1); //这一行的下一个
lie[y]^=ip;
hang[x]^=ip;
}
}
c[x][y]='.';
if((y+1)>n&&hang[x]==7) dfs(x+1,1);
else if(y+1<=n)dfs(x,y+1);
}
fire main() {
cin>>n>>s>>t;
s=" "+s;
t=" "+t;
dfs(1,1);
puts("No");
return false;
}

浙公网安备 33010602011771号