洛谷P1092 虫食算(算竞进阶习题)
模拟+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 虫食算(算竞进阶习题)的更多相关文章
- 洛谷P1092 虫食算
P1092 虫食算 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: http://paste.ubuntu.com/2544 ...
- 洛谷 P1092 虫食算 Label:dfs
题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中# ...
- [NOIP2004] 提高组 洛谷P1092 虫食算
题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中# ...
- 洛谷—— P1092 虫食算
https://www.luogu.org/problem/show?pid=1092 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简 ...
- 洛谷P1092虫食算——深搜
题目:https://www.luogu.org/problemnew/show/P1092 剪枝1:从右往左.从上往下按字母出现顺序搜索: 剪枝2:同一列前两个数字确定,可直接算出第三个数字并判断: ...
- 洛谷 p1092 虫食算
题目链接: https://www.luogu.org/problemnew/show/P1092 这个题折腾了我好久 这其实本质上是一道凑算式的题目 ,让一个二维数组存算式,一个一位数组存字母分别代 ...
- 【题解】 P1092虫食算
[题解]P1092 虫食算 老题了,很经典. 用到了一些搜索套路. 可行性剪枝,劣者靠后,随机化,\(etc......\) 搜索设参也很有技巧,设一个\(adjustment\)参数可以很方便地在两 ...
- Luogu P1092 虫食算(枚举+剪枝)
P1092 虫食算 题面 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 + 8468#6633 4 ...
- P1092 虫食算 题解(搜索)
题目链接 P1092 虫食算 解题思路 好题啊!这个搜索好难写...... 大概是要考虑进位和考虑使用过某个数字这两个东西,但就很容易出错...... 首先这个从后往前搜比较好想,按照从后往前出现的顺 ...
随机推荐
- 移动H5页面微信支付踩坑之旅(微信支付、单页面路由模拟、按钮加锁、轮询等常见功能)
开发背景: .net混合开发的vue模板语法的单页面应用,所以不存在脚手架以及没有路由可以跳转. 项目描述: 需要写两个页面,在订单详情页需要点击“请输入手机号”进入手机号绑定页面,手机号绑定成功后自 ...
- WEB学习感受
web学习感受 1.html前端知识比较好学,各种标签只需要记住关键的就行例如:body h1,p,div,tr,td,ul,li,就行了. 2.css学习前期还好, 后期关键布局和样式知识点较多,而 ...
- find和grep命令合集
linux grep命令 1.作用Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来.grep全称是Global Regular Expressi ...
- kuangbin 基础DP集合
HDU 1024第一遍水过,没有体会到这个题的奥妙,思考了很久终于体会了.大概意思是求把序列分成m段的子序列,并不一定要覆盖完,求子序列和的最大值我们首先要写出基本的动态转移方程: DP:dp[ i ...
- hibernate添加数据时Exception in thread "main" org.hibernate.PropertyValueException: not-null property references a null or transient value: com.javakc.hibernate.test.entity.TestEntity.testName
意思是,一个非null属性引用了一个null或瞬态值.就是在对应实体类配置文件hbm.xml中该属性配置了not-null="true",将其去掉即可.
- html总结:float实现span和input输入框同行
例: <input type="text" name="ytdwname" value="<%=user.getYtdwname() %& ...
- spring AOP的用法
AOP,面向切面编程,它能把与核心业务逻辑无关的散落在各处并且重复的代码给封装起来,降低了模块之间的耦合度,便于维护.具体的应用场景有:日志,权限和事务管理这些方面.可以通过一张图来理解下: Spri ...
- CLOUD流程设置
流程-反写规则 允许超额
- CSS实现元素水平垂直居中
我们知道,实现元素的水平居中比较简单,在设置了宽度后,设置左右margin为auto就可以. 但是如何设置元素垂直居中呢? 当然,对于单行的文字,可以通过设置line-height来解决, 可以对于一 ...
- js中获取当前项目名等
实际上通过window.location可以获取很多跟资源路径相关的信息,需要用到的时候直接通过浏览器调试可以查看window.location的一些属性