code1064 虫食算

dfs搜索每个字母对应的数字

剪枝:

1.当一列上三个数a b c都已知时,如果 (a+b)%n!=c && (a+b+1)%n!=c 剪枝(+1是考量进位,注意&&)

2.考虑到我们根据每排数据剪枝的,我们可以改变一下搜索的顺序,按照字母从上往下,从右往左出现的顺序来搜

3.因为我们是从最低位开始搜的,而且,3个数全都是N位,所以高位数组一般较小,低位较大,所以 应该从n-1倒过来搜(高位太大和就不是N位了)

代码:

#include<iostream>
#include<cstdlib>
#include<cstring>
#define Size 30
using namespace std;

int n;
int cc[3][Size];
int dic[Size]={0,  1,0,3,4,2};
bool vis[Size];

bool row(int i){
    if(dic[cc[0][i]]!=-1&&dic[cc[1][i]]!=-1&&dic[cc[2][i]]!=-1){
        int k=dic[cc[0][i]]+dic[cc[1][i]];
        if(k%n!=dic[cc[2][i]] && (k+1)%n!=dic[cc[2][i]])return false;
    }
    return true;
}

int next(){
    for(int i=1;i<=n;i++){
        for(int j=0;j<3;j++){
            if(dic[cc[j][i]]==-1)return cc[j][i];
        }
    }
    return n+1;
}

bool check(){
    int dd[3][Size];
    for(int i=0;i<3;i++){
        for(int j=1;j<=n;j++){
            dd[i][j]=dic[cc[i][j]];
        }
    }
    int f[Size];
    memset(f,0,sizeof(f));
    for(int i=1;i<=n;i++){
        f[i]+=dd[0][i];f[i]+=dd[1][i];
        while(f[i]>=n)f[i]-=n,f[i+1]++;
        if(f[i]!=dd[2][i])return false;
    }
    return true;
}

void dfs(int k){
    if(k>n){
        if(check()){
            for(int i=1;i<=n;i++)cout<<dic[i]<<‘ ‘;
            exit(0);
        }
    }
    //jianzhi
    for(int i=1;i<=n;i++){//1
        if(!row(i))return;
    }

    for(int i=n-1;i>=0;i--){
        if(!vis[i]){
            dic[k]=i;
            vis[i]=true;
            dfs(next());
            vis[i]=false;
            dic[k]=-1;
        }
    }
}

int main(){
    freopen("1064.in","r",stdin);
    memset(dic,-1,sizeof(dic));
    cin>>n;
    char temp[Size];
    for(int i=0;i<3;i++){
        cin>>temp+1;
        for(int j=1;j<=n;j++){
            cc[i][j]=temp[n-j+1]-64;
        }
    }
    dfs(next());
    return 0;
} 
测试点#alpha1.in  结果:AC    内存使用量:  256kB     时间使用量:  1ms     测试点#alpha10.in  结果:AC    内存使用量:  256kB     时间使用量:  1ms     测试点#alpha2.in  结果:AC    内存使用量:  256kB     时间使用量:  1ms     测试点#alpha3.in  结果:AC    内存使用量:  256kB     时间使用量:  1ms     测试点#alpha4.in  结果:AC    内存使用量:  256kB     时间使用量:  1ms     测试点#alpha5.in  结果:AC    内存使用量:  256kB     时间使用量:  1ms     测试点#alpha6.in  结果:AC    内存使用量:  256kB     时间使用量:  31ms     测试点#alpha7.in  结果:AC    内存使用量:  256kB     时间使用量:  3ms     测试点#alpha8.in  结果:AC    内存使用量:  256kB     时间使用量:  78ms     测试点#alpha9.in  结果:AC    内存使用量:  256kB     时间使用量:  1ms
时间: 2024-12-21 10:54:57

code1064 虫食算的相关文章

NOIP2004 虫食算

四.虫食算 (alpha.pas/dpr/c/cpp) [问题描述] 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045     +    8468#6633        44445506978 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许

69. [NOIP2004] 虫食算

69. [NOIP2004] 虫食算 ★★★   输入文件:alpha.in   输出文件:alpha.out   简单对比时间限制:1 s   内存限制:128 MB [问题描述] 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045    + 8468#6633 ----------- 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是

深度优先搜索 codevs 1064 虫食算

codevs 1064 虫食算 2004年NOIP全国联赛提高组 时间限制: 2 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045    +    8468#6633       44445506978 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5

noip 虫食算 (搜索)

描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子:43#9865#045+ 8468#6633= 44445506678其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制:首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用相同的字

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

题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用

洛谷—— P1092 虫食算

https://www.luogu.org/problem/show?pid=1092 题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: http://paste.ubuntu.com/25448822/ 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前

虫食算

题目描述 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +8468#6633 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的,我们将相同的数字用

【NOIP2004】虫食算

Description 所谓虫食算,就是原先的算式中有一部分被虫子啃掉了,需要我们根据剩下的数字来判定被啃掉的字母.来看一个简单的例子: 43#9865#045 +   8468#6633 44445509678 其中#号代表被虫子啃掉的数字.根据算式,我们很容易判断:第一行的两个数字分别是5和3,第二行的数字是5. 现在,我们对问题做两个限制: 首先,我们只考虑加法的虫食算.这里的加法是N进制加法,算式中三个数都有N位,允许有前导的0. 其次,虫子把所有的数都啃光了,我们只知道哪些数字是相同的

DFS——jzyzoj1187:虫食算

卡了两天的虫食算,调了一天的错误代码.给出题面: 没错题目很长,不过实际上就是给出三个n位数的字符串,每个大写字母都代表唯一的数字,让第一个字符串与第二个字符串相加,使得前两个字符串构成的N位数字相加后等于第三个字符串所代表的N位数字.按照字典序输出各个大写字母对应的值. 暴力的方法非常简单.用简单的dfs+回溯搜索每一个大写字母出现的值然后相加(注意进制以及进位),如果最终结果符合条件的话退出即可. 代码: 1 //暴力 2 #include <iostream> 3 #include &l