234234234

字串数字《蓝桥杯2019初赛》

题目:结果为: 3725573269

 

 

 

我有两种解法:

第一种:常规解法(模拟)。该解法时间太长,只能解比较短的字母串。

第二种:数位遍历 (没加dp,哎,实力问题) (最近,刚好自己在学位数dp入门,突然想到,没有基础的可以去另外学习)

如果有其他解法和错误,兄弟些请留下链接和意见。

 

第一种:直接上代码,代码里有个别说明的会在旁边加上注解

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>

#define ll long long

using namespace std;

ll method1(const string tar) {
    string s = "A";
    if (tar == "A") return 1; 
    for (ll i = 2;; i++) {
        int j = 0; // 表示进位 
        int k;
        // 模拟 
        // 这里可以按十进制加1满10进1的想法来做 
        // 不过这里是满'Z'加1 
        for (k = s.size()-1,s[k]++/*在最后一位加1*/; k >= 0; k--) {
            int p = s[k]+j;
            j = p/('Z'+1);
            s[k] = p % ('Z'+1);
            if (s[k] == 0) s[k] = 'A';
            if (j == 0) break;
        }
        // 再判断一下k的值
        if (j) s = "A" + s;
        if (s == tar) return i; // 与目标串相匹配,返回对应的数字 
    }
}

int main() {
    cout << method1("LANQIAO") << endl;
    return 0;
}

 

 

第二种:位数遍历(由于数位刚入门,不会加上dp(动态规划),等会了再补上)

 

#include <iostream>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>

#define ll long long

using namespace std;

int arr[30];// 抽象一下 A-Z变成1到26 
int dp[30]; // 记忆化数组 

ll dfs(int pos, bool limit, bool head) {
    if (pos == -1) {
        if (head) return 0; // 排除全是0的情况,其实也可以再最后的结果减1 
        return 1;
    }
    ll tal = 0;
    char up = limit?arr[pos]:26; 
    for (int i = 0; i <= up; i++) {
        // 这里解释一下,为了避免出现  X0XXX,其中 1 <= x <= 26 , 表示A-Z 
if (!head && i == 0) continue; tal+=dfs(pos-1, limit && i == arr[pos], i == 0 && head); } return tal; } ll solve(const string &s) { int pos = 0; for (int i = s.size()-1; i >= 0; i--) { arr[pos++] = s[i]-'A'+1; } vector<char> p; return dfs(pos-1, true, true); } int main() { cout << solve("LANQIAO") << endl; return 0; }

 

over........

 

posted @ 2020-02-22 19:43  你若愿意,我一定去  阅读(411)  评论(0编辑  收藏  举报
23423423423