算法学习记录(模拟枚举贪心题单):[NOIP2007]字符串的展开(未AC,明天找bug)

发布时间 2023-05-21 19:39:12作者: 想个昵称好难ABCD

题目链接

https://ac.nowcoder.com/acm/contest/20960/1001

解题思路

很简单的模拟题,以后写模拟要先分两大类,元素在某个集合中存不存在的问题,再细分。

未AC代码

#include <iostream>
#include <string>

using namespace std;

// 碰到'-'的展开条件:
//		1.减号两侧同为小写字母或数字,是ASKII的顺序,右边字符 > 左边字符
// 参数介绍:
//		p1:
//			p1 = 1:对于字符子串填充小写字母
//			p1 = 2:填充大写字母
//			p1 = 3:等价字母数量的 相同 *
//		p2:
//			当p2 = k,填充k个重复字,两侧字符不变
//
//		p3:
//			p3 = 1:维持原有顺序
//			p3 = 2:采用逆序输出
//			(不包括两端字符)
//		
//	如果'-'右侧字符是左侧字符后继,只删除中间减号

int p1, p2, p3;


string generate(string& str)
{
    string res;
    // 处理 p2(重复)
    
    for (char c = str[0]; c <= str[str.size() - 1]; ++ c)
        for (int i = 0; i < p2; ++ i)   
            res.push_back(c);

    if (p3 == 1);    // 顺序
    else if (p3 == 2)        // 逆序
            for (int i = 0, j = res.size() - 1; i < j; ++ i, -- j) 
            swap(res[i],res[j]);

    if (p1 == 3)        // 判 '*',
        for (int i = 0; i < res.size(); ++ i)
        res[i] = '*';
    
    if (isdigit(res[0])) return res;    // 如果是数字下面的可以不用看了

    // if (p1 == 1);       // 小写字母
    if (p1 == 2)           // 大写字母
        for (int i = 0; i < res.size(); ++ i)
        res[i] -= 32;
    
    return res;
}

int main()
{
    string str;
    cin >> p1 >> p2 >> p3 >> str;

    
    // 展开要填充的字符,注意后继
    for (int i = 0; i < str.size(); ++ i)
    {      
        if (str[i] == '-')
        {
            if (str[i + 1] - str[i - 1] == 1);        // 不输出'-'
            else if (str[i + 1] - str[i - 1] <= 0) cout << str[i];     // '-'不展开   
            else
            {
                char st, ed; 
                string tmp;
                st = str[i - 1], ed = str[i + 1];
                while (st < ed - 1) tmp.push_back( ++ st);      // 取出的是小写字母
                string res = generate(tmp);
                cout << res;

            }
        }
        else cout << str[i];
    }
    
    return 0;
}