vijos P1099虫食算【搜索

来源:互联网 发布:阿里云系统看电视 编辑:程序博客网 时间:2024/06/06 08:32

……好嘛终于下定决心写一把大暴搜【以为自己码力会清空23333】

然而发现怎么…………为什么……我的200+行毫不犹豫地又WA又T只能过样例,完全不想调啊【眼神死

去看了某大爷的题解……大概思路就是从右往左的字母分别枚举,每次check一下可不可能满足,如果不可能就return(这是个大剪枝),然后在枚举完了的时候,check一下等式是否成立…………

然而……这样只有80…………神tm卡掉两个点。

这个时候……对于每个字母的赋值从大往小就直接过了【想了一下觉得不是特别有道理,大概是玄学?有某些blog表示是因为低位有进位,我觉得是瞎扯淡】


不过啊…………这样写…………只有70行而且跑得很快,好写好调,直接一把就A了【除了初值上有点小bug23333】

凭什么大暴搜这么好写啊2333


所以我还是没有掌握优秀的搜索技巧啊2333

哪天写一把mayan【畏惧脸】

#include<bits/stdc++.h>#define MAXN 30using 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);}elsereturn ;}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;}


0 0
原创粉丝点击