The 15th Chinese Northeast Collegiate Programming Contest M. Master of Shuangpin

12 篇文章 0 订阅

直接模拟 分情况讨论就好 如果会一些string处理的库函数(eg. substr)处理起来会比较方便

代码有注释

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<queue>
#include<stack>
#include<map>
#include<unordered_map>
#include<set>

#pragma GCC optimize(2)
using namespace std;
#define ll long long
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define fi first
#define se second
#define pb push_back
#define debug(a) cout << #a << " " << a << '\n';
const int N = 5005;
const int M = 1e5 + 5;
const int INF = 0x3f3f3f3f;
const ll LLINF = 0x3f3f3f3f3f3f3f3f;
const ll mod = 1e9 + 7;

inline ll read();

int n, m;
vector<string> v[1005];//存输入
string ans[1005][1005];//存答案
bool st[1005][1005];//已经被操作过的串标记一下 以免重复操作
unordered_map<string, string> mp;

int main() {
    //ios::sync_with_stdio(false);
    mp["iu"] = "q", mp["en"] = "f", mp["ei"] = "w", mp["eng"] = "g";
    mp["ang"] = "h", mp["uan"] = "r", mp["an"] = "j", mp["ue"] = "t";
    mp["uai"] = "k", mp["ing"] = "k", mp["un"] = "y", mp["uang"] = "l";
    mp["iang"] = "l", mp["sh"] = "u", mp["ou"] = "z", mp["ch"] = "i";
    mp["ia"] = "x", mp["ua"] = "x", mp["uo"] = "o", mp["ao"] = "c";
    mp["ie"] = "p", mp["zh"] = "v", mp["ui"] = "v", mp["in"] = "b";
    mp["ong"] = "s", mp["iong"] = "s", mp["iao"] = "n", mp["ai"] = "d";
    mp["ian"] = "m";
    for (int i = 0; i < 26; i++) {
        string s;
        s += char('a' + 0);
        mp[s] = s;
    }
    string s;
    int d = 0;
    while (getline(cin, s)) { //处理输入
        //if(s=="0")break;
        string tmp;
        for (int i = 0; i < s.length(); i++) {
            if (s[i] == ' ') {
                v[d].pb(tmp);
                tmp.clear();
            } else {
                tmp += s[i];
            }

        }
        v[d].pb(tmp);
        d++;
    }
    for (int i = 0; i < d ; i++) {
        for (int j = 0; j < v[i].size(); j++) {
            if (v[i][j].size() == 1) { //只有一个字母的情况 直接复制 eg:a->aa b->bb...
                ans[i][j] = v[i][j];
                ans[i][j] += v[i][j];
                st[i][j] = true;
            } else if (v[i][j].size() == 2) {//两个字母的情况:不用做任何操作,答案直接是它本身
                ans[i][j] = v[i][j];
                st[i][j] = true;
            } else {
                for (auto t:mp) {//单独一个 例如ang之类的情况

                    if (t.fi == v[i][j]) {
                        ans[i][j] = t.fi[0];
                        ans[i][j] += t.se;
                        st[i][j] = true;
                    }
                }
            }
        }
    }

    for (int i = 0; i < d ; i++) {
        for (int j = 0; j < v[i].size(); j++) {//声母是单个的情况,除了声母以外一定能找到一个长度大于1的韵母
            if (!st[i][j] && mp.find(v[i][j].substr(1)) != mp.end()) {
                ans[i][j] = v[i][j][0];
                ans[i][j] += mp[v[i][j].substr(1)];
                st[i][j] = true;
            }
            if (!st[i][j] && mp.find(v[i][j].substr(0, 2)) != mp.end()) {//声母是两个的情况 例如ch sh
                ans[i][j] = mp[v[i][j].substr(0, 2)];
                if (v[i][j].size() <= 3) { //只剩下一个韵母 答案直接加上它
                    ans[i][j] += v[i][j][2];
                } else {
                    if (mp.find(v[i][j].substr(2)) != mp.end()) {//剩下两个韵母
                        ans[i][j] += mp[v[i][j].substr(2)];
                    }
                }
                st[i][j] = true;
            }
        }
    }
    for (int i = 0; i < d ; i++) {
        for (int j = 0; j < v[i].size(); j++) {
            cout << ans[i][j] ;
            if(j<v[i].size()-1)cout<<' ';
        }
        if(i<d-1)puts("");
    }
    return 0;
}


inline ll read() {
    char ch = getchar();
    ll p = 1, data = 0;
    while (ch < '0' || ch > '9') {
        if (ch == '-')p = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9') {
        data = data * 10 + (ch ^ 48);
        ch = getchar();
    }
    return p * data;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值