模拟+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. 大连CCPC D - A Simple Math Problem

    #include<iostream> #include<string.h> #include<stdio.h> #include<algorithm> ...

  2. Python之切片操作

    1.列表list中使用 1.range()生成器 就是list取值的一种方式. 生成器range(),用于写列表的范围,如果只写一个数,就表示从0开始,到写入的值-1: l=list(range(10 ...

  3. axios的增删改查。

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  4. Vue+min-width实现最大两栏布局

    <style> .fitting-Modal-details{ overflow: hidden; } .detailsContent{ float: left; min-width: 5 ...

  5. Oracle RMAN备份与还原注意事项

    1 备份文件管理 如果要删除之前的备份,不要手动去目录下删除,应该在rman命令模式下使用删除命令,否则虽然在磁盘上把物理备份文件删除了,但是使用备份查看命令会一直看到已经删除的备份文件 list b ...

  6. [转帖]PAT 计算机程序设计能力考试

    PAT 计算机程序设计能力考试 https://blog.csdn.net/bat67/article/details/52134211 [官方简介] 计算机程序设计能力考试(Programming ...

  7. pojo类自动生成序列化ID

    自动生成序列化ID

  8. Codeforces 1154G Minimum Possible LCM

    题目链接:http://codeforces.com/problemset/problem/1154/G 题目大意: 给定n个数,在这些数中选2个数,使这两个数的最小公倍数最小,输出这两个数的下标(如 ...

  9. python之对字符串类型的数组求平均值

    该字符串是在网页表格中复制的,所以数字间由制表符间隔,先将其转换成列表,再进行统计计算.代码如下: str = "-18.1 -18.3 -18 -18.2 -18 -17.4 -18 -1 ...

  10. react 入坑笔记(三) - Props

    React Props props - 参数. 组件类 React.Component 有个 defaultProps 属性,以 class xxx extend React.Component 形式 ...