P1092 虫食算

题目描述

所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母。来看一个简单的例子:

http://paste.ubuntu.com/25448822/

其中#号代表被虫子啃掉的数字。根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5。

现在,我们对问题做两个限制:

首先,我们只考虑加法的虫食算。这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0。

其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用相同的字母表示,不同的数字用不同的字母表示。如果这个算式是N进制的,我们就取英文字母表午的前N个大写字母来表示这个算式中的0到N-1这N个不同的数字:但是这N个字母并不一定顺序地代表0到N-1)。输入数据保证N个字母分别至少出现一次。

http://paste.ubuntu.com/25448824/

上面的算式是一个4进制的算式。很显然,我们只要让ABCD分别代表0123,便可以让这个式子成立了。你的任务是,对于给定的N进制加法算式,求出N个不同的字母分别代表的数字,使得该加法算式成立。输入数据保证有且仅有一组解

输入输出格式

输入格式:

包含四行。第一行有一个正整数N(N<=26),后面的3行每行有一个由大写字母组成的字符串,分别代表两个加数以及和。这3个字符串左右两端都没有空格,从高位到低位,并且恰好有N位。

输出格式:

包含一行。在这一行中,应当包含唯一的那组解。解是这样表示的:输出N个数字,分别表示A,B,C……所代表的数字,相邻的两个数字用一个空格隔开,不能有多余的空格。

输入输出样例

输入样例#1:

5
ABCED
BDACE
EBBAA
输出样例#1:

1 0 3 4 2

说明

对于30%的数据,保证有N<=10;

对于50%的数据,保证有N<=15;

对于全部的数据,保证有N<=26。

noip2004提高组第4题

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,map[],lena,lenb,lenc;
char a1[],b1[],c1[];
bool vis[],flag;
int aa[],bb[],cc[],a[],b[],c[];
bool check(){
for(int i=;i<=n;i++)aa[i]=map[a[i]],bb[i]=map[b[i]],cc[i]=map[c[i]];
int d[];
memset(d,,sizeof(d));
for(int i=n;i>=;i--){
d[i]+=aa[i]+bb[i];
if(d[i]>=n)d[i-]+=d[i]/n,d[i]=d[i]%n;
}
if(d[])return ;
for(int i=;i<=n;i++)
if(d[i]!=cc[i])return ;
return ;
}
void dfs(int pos){
if(pos==n+){
if(check()){
for(int i=;i<=n;i++)printf("%d ",map[i]);
flag=;
}
return;
}
if(flag)return;
for(int i=;i<n;i++){
if(!vis[i]){
vis[i]=;
map[pos]=i;
dfs(pos+);
vis[i]=;
}
}
}
int main(){
freopen("Cola.txt","r",stdin);
scanf("%d",&n);
scanf("%s%s%s",a1+,b1+,c1+);
for(int i=;i<=n;i++){
a[i]=a1[i]-'A'+;
b[i]=b1[i]-'A'+;
c[i]=c1[i]-'A'+;
}
dfs();
}

30分 暴力枚举+代入检验 O(n!)

#include<iostream>
#include<cstdio>
#include<cstring>
#include<ctime>
using namespace std;
int n,map[],lena,lenb,lenc;
char a1[],b1[],c1[];
bool vis[],flag,v[];
int aa[],bb[],cc[],a[],b[],c[];
bool check(){
for(int i=;i<=n;i++)aa[i]=map[a[i]],bb[i]=map[b[i]],cc[i]=map[c[i]];
int d[];
memset(d,,sizeof(d));
for(int i=n;i>=;i--){
d[i]+=aa[i]+bb[i];
if(d[i]>=n)d[i-]+=d[i]/n,d[i]=d[i]%n;
}
if(d[])return ;
for(int i=;i<=n;i++)
if(d[i]!=cc[i])return ;
return ;
}
bool jianzhi(){
int w1,w2;
for(int i=;i<=n;i++){
if(v[a[i]]&&v[b[i]]&&v[c[i]]){
w1=map[a[i]]+map[b[i]];while(w1>=n)w1-=n;
w2=w1+;while(w2>=n)w2-=n;
if(w1!=map[c[i]] && w2!=map[c[i]])return ;
}
if(v[a[i]]&&v[b[i]]&&!v[c[i]]){
w1=map[a[i]]+map[b[i]];while(w1>=n)w1-=n;
w2=w1+;while(w2>=n)w2-=n;
if(vis[w1]&&vis[w2])return ;
}
if(v[a[i]]&&v[c[i]]&&!v[b[i]]){
w1=map[c[i]]-map[a[i]];while(w1<)w1+=n;
w2=w1-;while(w2<)w2+=n;
if(vis[w1]&&vis[w2])return ;
}
if(v[b[i]]&&v[c[i]]&&!v[a[i]]){
w1=map[c[i]]-map[b[i]];while(w1<)w1+=n;
w2=w1-;while(w2<)w2+=n;
if(vis[w1]&&vis[w2])return ;
}
}
return ;
}
void dfs(int pos){
if(flag)return;
if(jianzhi())return;
if(pos==n+){
if(check()){
for(int i=;i<=n;i++)printf("%d ",map[i]);
flag=;
}
return;
}
for(int i=;i<n;i++){
if(!vis[i]){
vis[i]=;
map[pos]=i;
v[pos]=;
dfs(pos+);
if(flag)return;
vis[i]=;
v[pos]=;
}
}
}
int main(){
//freopen("Cola.txt","r",stdin);
scanf("%d",&n);
scanf("%s%s%s",a1+,b1+,c1+);
for(int i=;i<=n;i++){
a[i]=a1[i]-'A'+;
b[i]=b1[i]-'A'+;
c[i]=c1[i]-'A'+;
}
dfs();
}

70分 加两个剪枝(倒着枚举是50分)

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int n;
char a[],b[],c[];
int s1[],s2[],s3[];
int cnt,net[],use[],num[];
bool jz(){
if(num[s1[]]+num[s2[]]>=n) return true;
for(int i=n-;i>=;i--){
int A=num[s1[i]],B=num[s2[i]],C=num[s3[i]];
if(A==-||B==-||C==-) continue;
if((A+B)%n!=C&&(A+B+)%n!=C)
return true;
}
return false;
}
bool judge(){
for(int i=n-,x=;i>;i--){
int A=num[s1[i]],B=num[s2[i]],C=num[s3[i]];
if((A+B+x)%n!=C) return false;
x=(A+B+x)/n;
}
return true;
}
void dfs(int now){
if(jz()==true) return ;
if(now==n)
if(judge()==true){
for(int i=;i<n;i++)
cout<<num[i]<<" ";
exit();
}
for(int i=n-;i>=;i--){
if(use[i]==){
num[net[now]]=i;
use[i]=;
dfs(now+);
num[net[now]]=-;
use[i]=;
}
}
}
void getnet(int x){
if(use[x]==){
net[cnt++]=x;
use[x]=;
}
return ;
}
int main(){
scanf("%d",&n);
scanf("%s%s%s",a,b,c);
for(int i=;i<n;i++){
s1[i]=a[i]-'A';
s2[i]=b[i]-'A';
s3[i]=c[i]-'A';
}
for(int i=n-;i>=;i--){
getnet(s1[i]);
getnet(s2[i]);
getnet(s3[i]);
}
memset(use,,sizeof(use));
memset(num,-,sizeof(num));
dfs();
return ;
}

100分

洛谷P1092 虫食算的更多相关文章

  1. 洛谷 P1092 虫食算 Label:dfs

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

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

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

  3. 洛谷—— P1092 虫食算

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

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

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

  5. 洛谷 p1092 虫食算

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

  6. 洛谷P1092 虫食算(算竞进阶习题)

    模拟+dfs 这个题就三行,搜索的话我们从右向左,从上到下.. 如果是在1,2行我们就直接枚举0-n所有数,但是到了第三行,最直接的就是填上这一列上前两行的数的和modN,在此基础上判断该填的数有没有 ...

  7. 【题解】 P1092虫食算

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

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

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

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

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

随机推荐

  1. adb命令(一)

    针对移动端 Android 的测试, adb 命令是很重要的一个点,必须将常用的 adb 命令熟记于心, 将会为 Android 测试带来很大的方便,其中很多命令将会用于自动化测试的脚本当中. And ...

  2. 201621123014《JAVA程序设计》第1周学习总结

    1. 本章学习总结 关键字:JAVA特点.JDK.JVM.JRE.class.编译工具.JDK是JAVA的开发工具包,拥有JAVA需要的环境和各类JAVA工具,是JAVA的核心:JVM是JAVA虚拟机 ...

  3. L106 Three things we learned from day one at the World Cup

    Hosts Russia got the World Cup off to a flying start by hammering Saudi Arabia 5-0 in the opening ga ...

  4. 【LeetCode】021. Merge Two Sorted Lists

    Merge two sorted linked lists and return it as a new list. The new list should be made by splicing t ...

  5. Qt安装与配置

    安装Qt 安装Qt Creator,打开终端执行如下命令: sudo apt-get install qt5-default qtcreator -y 安装Qt示例和文档: sudo apt-get ...

  6. Android ANR原因以及开发时如何预防

    经常可以在Android系统上发现ANR异常响应的问题.故了解一下ANR出现的原因 一. Android系统中,应用程序的响应是由ActivityManager 和 WindowManger系统服务监 ...

  7. Android Studio的Android Monitor窗口中把标签拉出来之后放不回去的解决方法

    不小心把下图方框中的logcat标签拖出来之后, 就变成了图2的浮动窗口,发现logcat标签怎么也弄不回原来窗口中的位置中. 其实解决方法很简单,只要拖住下图浮动窗口中红框位置的logcat标签,然 ...

  8. paramiko使用1

  9. linux命令-bzip2压缩

    gzip和bzip2 都是压缩命令  区别是压缩算法不一样  一般bzip2压缩的效率高  都不能压缩目录 bzip2 压缩 [root@wangshaojun ~]# bzip2 install.l ...

  10. Spring开发包介绍

    -----------------siwuxie095                         核心开发包         建立 Spring 工程时,需要引入 Spring 的开发包,否则无 ...