模拟+dfs

这个题就三行,搜索的话我们从右向左,从上到下。。

如果是在1,2行我们就直接枚举0~n所有数,但是到了第三行,最直接的就是填上这一列上前两行的数的和modN,在此基础上判断该填的数有没有被使用

如果没有被使用,且这个地方没有被赋值,就可以把要填的数填上去,如果被填了切符合要求,就不需要填数了。。注意每次填数都要维护下一列进位的值以及回溯

有一个非常重要的剪枝就是:对于一个竖式a+b=c,如果(a+b)modn != c 且 (a + b + 1)modn != c,那么这个竖式就是错的,可以直接返回

#include <bits/stdc++.h>
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
inline int lowbit(int x){ return x & (-x); }
inline int read(){
int X = 0, w = 0; char ch = 0;
while(!isdigit(ch)) { w |= ch == '-'; ch = getchar(); }
while(isdigit(ch)) X = (X << 3) + (X << 1) + (ch ^ 48), ch = getchar();
return w ? -X : X;
}
inline int gcd(int a, int b){ return a % b ? gcd(b, a % b) : b; }
inline int lcm(int a, int b){ return a / gcd(a, b) * b; }
template<typename T>
inline T max(T x, T y, T z){ return max(max(x, y), z); }
template<typename T>
inline T min(T x, T y, T z){ return min(min(x, y), z); }
template<typename A, typename B, typename C>
inline A fpow(A x, B p, C lyd){
A ans = 1;
for(; p; p >>= 1, x = 1LL * x * x % lyd)if(p & 1)ans = 1LL * x * ans % lyd;
return ans;
} int n, num[40], cnt, c[40];
bool vis[40], flag;
char s[4][40]; bool check(int col){
for(int i = col - 1; i >= 1; i --){
if(num[s[1][i] - 'A' + 1] != -1 && num[s[2][i] - 'A' + 1] != -1 && num[s[3][i] - 'A' + 1] != -1){
int a = num[s[1][i] - 'A' + 1], b = num[s[2][i] - 'A' + 1];
int d = num[s[3][i] - 'A' + 1];
if((a + b) % n != d && (a + b + 1) % n != d) return false;
}
}
return true;
} void dfs(int row, int col){
//cout << row << " " << col << endl;
if(flag) return;
if(cnt == n || (col == 0 && c[col] == 0)){
flag = true;
for(int i = 1; i <= n; i ++) printf("%d ", num[i]);
puts("");
return;
}
if(row != 3){
if(num[s[row][col] - 'A' + 1] == -1){
for(int i = 0; i < n; i ++){
if(vis[i]) continue;
vis[i] = true, num[s[row][col] - 'A' + 1] = i, cnt ++;
if(check(col)) dfs(row + 1, col);
vis[i] = false, num[s[row][col] - 'A' + 1] = -1, cnt --;
}
}
else dfs(row + 1, col);
}
else{
int a = num[s[1][col] - 'A' + 1], b = num[s[2][col] - 'A' + 1];
int d = (a + b + c[col]) % n;
if(num[s[row][col] - 'A' + 1] == -1){
if(vis[d]) return;
vis[d] = true, num[s[row][col] - 'A' + 1] = d, c[col - 1] = (a + b + c[col]) / n, cnt ++;
if(check(col)) dfs(1, col - 1);
vis[d] = false, num[s[row][col] - 'A' + 1] = -1, c[col - 1] = 0, cnt --;
}
else{
if(num[s[row][col] - 'A' + 1] != d) return;
c[col - 1] = (a + b + c[col]) / n;
if(check(col)) dfs(1, col - 1);
c[col - 1] = 0;
}
}
} int main(){ n = read();
for(int i = 1; i <= 3; i ++) scanf("%s", s[i] + 1);
flag = false, memset(num, -1, sizeof num);
dfs(1, n);
return 0;
}

洛谷P1092 虫食算(算竞进阶习题)的更多相关文章

  1. 洛谷P1092 虫食算

    P1092 虫食算 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: http://paste.ubuntu.com/2544 ...

  2. 洛谷 P1092 虫食算 Label:dfs

    题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中# ...

  3. [NOIP2004] 提高组 洛谷P1092 虫食算

    题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中# ...

  4. 洛谷—— P1092 虫食算

    https://www.luogu.org/problem/show?pid=1092 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简 ...

  5. 洛谷P1092虫食算——深搜

    题目:https://www.luogu.org/problemnew/show/P1092 剪枝1:从右往左.从上往下按字母出现顺序搜索: 剪枝2:同一列前两个数字确定,可直接算出第三个数字并判断: ...

  6. 洛谷 p1092 虫食算

    题目链接: https://www.luogu.org/problemnew/show/P1092 这个题折腾了我好久 这其实本质上是一道凑算式的题目 ,让一个二维数组存算式,一个一位数组存字母分别代 ...

  7. 【题解】 P1092虫食算

    [题解]P1092 虫食算 老题了,很经典. 用到了一些搜索套路. 可行性剪枝,劣者靠后,随机化,\(etc......\) 搜索设参也很有技巧,设一个\(adjustment\)参数可以很方便地在两 ...

  8. Luogu P1092 虫食算(枚举+剪枝)

    P1092 虫食算 题面 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 + 8468#6633 4 ...

  9. P1092 虫食算 题解(搜索)

    题目链接 P1092 虫食算 解题思路 好题啊!这个搜索好难写...... 大概是要考虑进位和考虑使用过某个数字这两个东西,但就很容易出错...... 首先这个从后往前搜比较好想,按照从后往前出现的顺 ...

随机推荐

  1. Stack Sorting CodeForces - 911E (思维+单调栈思想)

    Let's suppose you have an array a, a stack s (initially empty) and an array b (also initially empty) ...

  2. Applese 的毒气炸弹 G 牛客寒假算法基础集训营4(图论+最小生成树)

    链接:https://ac.nowcoder.com/acm/contest/330/G来源:牛客网 Applese 的毒气炸弹 时间限制:C/C++ 2秒,其他语言4秒 空间限制:C/C++ 262 ...

  3. 书城项目第五阶段---book表的curd

    JavaEE三层架构分析 MVC

  4. git [command line] fatal: Authentication failed for

    fatal: Authentication failed for https://www.jianshu.com/p/8a7f257e07b8 git.exe fetch -v --progress ...

  5. 网站数据分析&初始来源

    数据分析:如何追踪访客初始来源_搜索学院_百度搜索资源平台 https://ziyuan.baidu.com/college/articleinfo?id=260 网站数据分析:如何追踪访客初始来源 ...

  6. vue上传图片

    在用这块代码前需要在主页面index引入<script src="http://at.alicdn.com/t/font_kfbh2nlnqrrudi.js">< ...

  7. CIFS 与 SMB 有什么区别?

    CIFS 与 SMB 有什么区别? https://www.getnas.com/2018/11/30/cifs-vs-smb/ 网络协议 一知半解 学习一下挺好的.. 记得 win2019 已经废弃 ...

  8. outline,box-shadow,border-radius小例子

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

  9. django之路由层

    一 Django中路由的作用 二 简单的路由配置 三 有名分组 四 路由分发 五 反向解析 六 名称空间 七 django2.0版的path 一 Django中路由的作用 URL配置(URLconf) ...

  10. python爬虫之多线程、多进程、GIL锁

    背景: 我们知道多线程要比多进程效率更高,因为线程存在于进程之内,打开一个进程的话,首先需要开辟内存空间,占用内存空间比线程大.这样想也不怪,比如一个进程用10MB,开10个进程就得100MB的内存空 ...