zoukankan      html  css  js  c++  java
  • LeetCode 1307 口算难题

    这道题就是给出字符串,字符串中的每一个字符代表一个数字,字符和数字是一一对应的,且保证不同的字符最多有十种,问给出的字符串是否存在映射使加法成立。描述的可能不是很清楚,详见原题---LeetCode 1307 口算难题。这道题是dfs+剪枝,纯暴力时间开销很大,我的想法是从每个字符串的最低位依次枚举,也就是依次枚举个位、十位、百位......然后到等式右边的时候,也就是结果,判定当前字符是否已经映射,是否可以映射成为等式左边几个数相加的和,这里的和只取个位就可以,因为我是按位枚举的,还有一点要注意的是进位,并且到最后判断是否有数字出现前导0,我在预处理数据时把所有的字符串倒置了,方便接下来的运算。整体有一定难度,更重要的是所有的细节都要考虑到,很棒的一道题。

    class Solution {
    
    public:
        int mp[300],rsct;
        int wdsz[10],wdct;
        int vis[10],jinwei[10],maxn;
        bool dfs(int now,int pos,vector<string>& words, string result)
        //第几个数字,第几位
        {
            if(pos==maxn) 
            {
                for(int i=0;i<wdct;i++)
                if(mp[words[i][wdsz[i]-1]]==0) return false;
                if(mp[result[rsct-1]]==0) return false;
                return true;
            }
            if(now<wdct)
            {
                if(pos<wdsz[now])
                {
                    if(mp[words[now][pos]]==-1)
                    {
                        for(int i=0;i<10;i++)
                        if(!vis[i])
                        {
                            vis[i]=1;
                            mp[words[now][pos]]=i;
                            if(dfs(now+1,pos,words,result)) return true;
                            mp[words[now][pos]]=-1;
                            vis[i]=0;
                        }
                        
                    }
                    else 
                    {
                        if(dfs(now+1,pos,words,result)) return true;
                    }
                }
                else
                {
                    if(dfs(now+1,pos,words,result)) return true;
                }
            }
            else if(now==wdct)
            {
                int ans=0;
                for(int i=0;i<wdct;i++)
                {
                    if(pos<wdsz[i]) ans+=mp[words[i][pos]];
                }
                if(pos>0) ans+=jinwei[pos-1];
                jinwei[pos]=ans/10;
                ans=ans%10;
                if(rsct<=pos)
                {
                    if(ans!=0) return false;
                    else return dfs(0,pos+1,words,result);
                }
                else
                {
                    if(mp[result[pos]]==-1)
                    {
                        if(vis[ans]==1) return false;
                        else
                        {
                            vis[ans]=1;
                            mp[result[pos]]=ans;
                            if(dfs(0,pos+1,words,result)) return true;
                            vis[ans]=0;
                            mp[result[pos]]=-1;
                        }
                    }
                    else
                    {
                        if(mp[result[pos]]!=ans) return false;
                        else return dfs(0,pos+1,words,result);
                    }
                }
            }
    
            return false;
        }
        bool isSolvable(vector<string>& words, string result) {
            wdct=words.size();
            rsct=result.size();
            maxn=rsct;
            memset(mp,-1,sizeof(mp));
            for(int i=0;i<wdct;i++)
            {
                wdsz[i]=words[i].size();
                reverse(words[i].begin(),words[i].end());
                maxn=max(wdsz[i],maxn);
            }
            reverse(result.begin(),result.end());
            return dfs(0,0,words,result);
        }
    };
    
  • 相关阅读:
    KT_登录_流程图
    从零开始——电子商务平台02_遇到的小问题
    从零开始——电子商务平台02
    COCOMOII
    从零开始——电子商务平台01_遇到的小问题
    从零开始——电子商务平台01
    从零开始——MySql01
    【 bzoj4537】HNOI2016 最小公倍数
    SDOI2016 R1 解题报告 bzoj4513~bzoj4518
    左偏树初步 bzoj2809 & bzoj4003
  • 原文地址:https://www.cnblogs.com/ambition-hhn/p/12824465.html
Copyright © 2011-2022 走看看