……好嘛终于下定决心写一把大暴搜【以为自己码力会清空23333】
然而发现怎么…………为什么……我的200+行毫不犹豫地又WA又T只能过样例,完全不想调啊【眼神死
去看了某大爷的题解……大概思路就是从右往左的字母分别枚举,每次check一下可不可能满足,如果不可能就return(这是个大剪枝),然后在枚举完了的时候,check一下等式是否成立…………
然而……这样只有80…………神tm卡掉两个点。
这个时候……对于每个字母的赋值从大往小就直接过了【想了一下觉得不是特别有道理,大概是玄学?有某些blog表示是因为低位有进位,我觉得是瞎扯淡】
不过啊…………这样写…………只有70行而且跑得很快,好写好调,直接一把就A了【除了初值上有点小bug23333】
凭什么大暴搜这么好写啊2333
所以我还是没有掌握优秀的搜索技巧啊2333
哪天写一把mayan【畏惧脸】
#include<bits/stdc++.h>
#define MAXN 30
using namespace std; int n;
int a[MAXN],b[MAXN],c[MAXN];
char read_s[MAXN];
int que[MAXN];
int mp[MAXN];
int ust[MAXN];
bool check1(){
for(int i=n-1;~i;--i){
int x=mp[a[i]],y=mp[b[i]],z=mp[c[i]];
if(x!=-1 && y!=-1 && z!=-1 &&
z!=(x+y)%n && z!=(x+y+1)%n)
return 0;
}
return 1;
}
bool check2(){
int now=0;
for(int i=n-1;~i;--i){
if(mp[a[i]]==-1||mp[b[i]]==-1||mp[c[i]]==-1) return 0;
now+=mp[a[i]]+mp[b[i]];
if(now%n!=mp[c[i]]) return 0;
now/=n;
}
if(now) return 0;
return 1;
}
void dfs(int now){
if(now>=n){
if(check2()){
for(int i=0;i<n;++i) printf("%d ",mp[i]);
exit(0);
}
else return ;
}
if(!check1()) return ;
for(int i=n-1;~i;--i){
if(!ust[i]){
mp[que[now]]=i;
ust[i]=1;
dfs(now+1);
ust[i]=0;
mp[que[now]]=-1;
}
}
}
int main(){
scanf("%d",&n);
scanf("%s",read_s); for(int i=0;i<n;++i) a[i]=read_s[i]-'A';
scanf("%s",read_s); for(int i=0;i<n;++i) b[i]=read_s[i]-'A';
scanf("%s",read_s); for(int i=0;i<n;++i) c[i]=read_s[i]-'A';
for(int i=n-1,j=0;~i;--i){
if(!ust[a[i]]) que[j++]=a[i],ust[a[i]]=1;
if(!ust[b[i]]) que[j++]=b[i],ust[b[i]]=1;
if(!ust[c[i]]) que[j++]=c[i],ust[c[i]]=1;
}
memset(mp,-1,sizeof mp);
memset(ust,0,sizeof ust);
dfs(0);
return 0;
}