洛谷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 虫食算 解题思路 好题啊!这个搜索好难写...... 大概是要考虑进位和考虑使用过某个数字这两个东西,但就很容易出错...... 首先这个从后往前搜比较好想,按照从后往前出现的顺 ...
随机推荐
- VS2017开发的IDE扩展
Tag Helpers 智能提示 Razor Language Services: https://marketplace.visualstudio.com/items?itemName=ms-mad ...
- Vue(二)基础
01-vue的起步 1.引包 a) 直接下载,并用<script>标签引入 b) CDN方式引入: <script src="https://cdn.bootcss.com ...
- 通过设置线程池的最小线程数来提高task的效率,SetMinThreads。
http://www.cnblogs.com/Charltsing/p/taskpoolthread.html task默认对线程的调度是逐步增加的,连续多次运行并发线程,会提高占用的线程数,而等若干 ...
- Python_架构、同一台电脑上两个py文件通信、两台电脑如何通信、几十台电脑如何通信、更多电脑之间的通信、库、端口号
1.架构 C/S架构(鼻祖) C:client 客户端 S:server 服务器 早期使用的一种架构,目前的各种app使用的就是这种架构,它的表现形式就是拥有专门的app. B/S架构(隶属于C/ ...
- Django组件之认证系统
Django自带的用户认证 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统.此时我们需要实现包括用户注册.用户登录.用户认证.注销.修改密码等功能,这还真是个麻烦的事情呢. Dja ...
- phantomjs 了解
转自:http://www.cnblogs.com/lei0213/ PhantomJS是一个无界面的,可脚本编程的WebKit浏览器引擎.它原生支持多种web 标准:DOM 操作,CSS选择器,JS ...
- [转帖]BRD、MRD 和 PRD
来源: https://www.zhihu.com/question/19655491 BRD 商业需求文档 Business Requirement Document MRD 市场需求文档 Mark ...
- vue-cli项目开发/生产环境代理实现跨域请求+webpack配置开发/生产环境的接口地址
一.开发环境中跨域 使用 Vue-cli 创建的项目,开发地址是 localhost:8080,需要访问非本机上的接口http://10.1.0.34:8000/queryRole.不同域名之间的访问 ...
- longquan
/** * 登录后将数据填写到主数据 */ public void login(String login_nr) { //File f = new File(android.os.Environmen ...
- python中的__init__和__new__的区别
一.__init__ 方法是什么?(init前后的线是双下划线) 使用Python写过面向对象的代码的同学,可能对 __init__ 方法已经非常熟悉了,__init__ 方法通常用在初始化一个类实例 ...