SMU 2024 spring 天梯赛2

7-1计算指数

gogogo

查看代码
 void solve() {
    int n;
    cin >> n;
    cout << "2^" << n << " = " << (int)pow(2, n);
}

 

7-2计算摄氏温度

good

查看代码
 void solve() {
    int f = 100;
    int c = 5 * (f - 32) / 9;
    cout << "fahr = " << f << ", celsius = " << c;
}

 

7-3念数字

go notbad

查看代码
void solve() {
    vector<string > ve(10);
    ve[0] = "ling", ve[1] = "yi", ve[2] = "er", ve[3] = "san", ve[4] = "si",
    ve[5] = "wu", ve[6] = "liu", ve[7] = "qi", ve[8] = "ba", ve[9] = "jiu";
    string s;
    cin >> s;
    for (int i = 0; i < s.size(); ++i) {
        if (s[i] == '-') cout << "fu";
        else cout << ve[s[i] - '0'];
        if (i < s.size() - 1) cout << ' ';
    }
}

 

7-4求阶乘累加和

gooood

查看代码
 void solve() {
    int n, sum = 0;
    cin >> n;
    for (int i = 1, p = 1; i <= n; ++i) {
        p *= i;
        sum += p;
    }
    cout << sum;
}

 

7-56翻了

思路:找出所有连续的6,用replace来替换

查看代码
 void solve() {
    string s;
    getline(cin, s);
    for (int i = 0; i < s.size(); ++i) {
        if (s[i] == '6') {
            int j = i;
            while (j + 1 < s.size() && s[j + 1] == '6') {
                j ++;
            }
            if (j - i + 1 > 9) {
                s.replace(i, j - i + 1, "27");
            } else if (j - i + 1 > 3) {
                s.replace(i, j - i + 1, "9");
            }
        }
    }
    cout << s << '\n';
}

 

7-6福到了

notbad

思路:用reverse来置换

查看代码
 void solve() {
    char op;
    int n;
    cin >> op >> n;getchar();
    vector<string > ve(n), t(n);
    for (int i = 0; i < n; ++i) {

        getline(cin, ve[i]);
        t[i] = ve[i];
        std::reverse(t[i].begin(), t[i].end());
    }
    bool ok = true;
    for (int i = 0, j = n - 1; i < n; ++i, --j) {
        if (ve[i] != t[j]) {
            ok = false;
            break;
        }
    }
    if (ok) cout << "bu yong dao le\n";
    for (int i = n - 1; i >= 0; --i) {
        for (int j = 0; j < n; ++j) {
            if (t[i][j] == '@') cout << op;
            else cout << ' ';
        }
        cout << '\n';
    }
}

 

7-7估值一亿的AI核心代码

ohhhhhno what

思路:需要注意一点,出现了you can 或 you could 后,you会变成 I ,而这个 I 不能再转换成 you

接下来就是狠狠模拟,可以将所有字符分段,保证每段的属性相同(字母,数字,符号,空格)

对串进行删减:

对于为字母的段,保证除了 I 以外全为小写

对于为数字的段,不用改变

对于为符号的段,不用改变

对于为空格的段,长度最长为1, 若其后面一段为符号,忽略掉该段空格

对串进行替换:

找到 can you 和 could you 后(注意中间有个空格段),将 空格段 和 you 删掉, 保存 I + 空格 + can 或 I + 空格 + could,这个时候将保存的这一段存成一段,如此一来,在将 I 替换成 you 这一操作时,不会再将转换后的 I can 或 I could 的 I 再次操作

最后就是逐个判断每个段是否是 I 或 me,将所有 ?换成 !

end

查看代码
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;


int f( char x ){
    if( x == ' ' ) return 0;
    if( x >= 'a' and x <= 'z' || x >= 'A' and x <= 'Z' ) return 1;
    if( x >= '0' and x <= '9' ) return 3;
    return 4;
}

void solve() {
    int n;
    cin >> n;
    getchar();
    auto toa = [](char c) {
        if (c == 'I') return c;
        if (c >= 'A' && c <= 'Z') return (char)(c + 32);
        return c;
    };
    auto check = [toa](string s) {
        vector<string> ve;
        string t;
        for ( int i = 0; i < s.size(); ++i) {
            if (t.empty() || f(s[i]) == f (s[i - 1])) {
                t.push_back(toa(s[i]));
            } else {
                ve.push_back(t);
                t.clear();
                t.push_back(toa(s[i]));
            }
        }
        if (!t.empty()) ve.push_back(t);
        while (!ve.empty() && ve.begin()->front() == ' ') ve.erase(ve.begin());
        while (!ve.empty() && ve.back().front() == ' ') ve.pop_back();
        vector<string > g;
        for (int i = 0; i < ve.size(); ++i) {
            if (ve[i].front() == ' ' && i + 1 < ve.size() && f(ve[i + 1].front()) == 4)continue;
            if (ve[i].front() == ' ' && ve[i].size() > 1) ve[i] = " ", g.push_back(ve[i]);
            else {
                if (f(ve[i].front()) == 4) {
                    for (int j = 0; j < ve[i].size(); ++j) {
                        if (ve[i][j] == '?') ve[i][j] = '!';
                    }
                }
                g.push_back(ve[i]);
            }
        }
        ve.swap(g);
        g.clear();
        for (int i = 0; i < ve.size(); ++i) {
            if ( i + 2 < ve.size() && ve[i + 2] == "you" && ve[i + 1] == " " && (ve[i] == "could" || ve[i] == "can") ) {
                g.push_back("I " + ve[i]);
                i += 2;
            } else g.push_back(ve[i]);
        }
        for (int i = 0; i < g.size(); ++i) {
            if (g[i] == "I" || g[i] == "me") g[i] = "you";
        }
        string ans;
        for (auto v:g) ans += v;
        return ans;

    };
    for (int i = 0; i < n; ++i) {
        string s;
        getline(cin, s);
        cout << s << '\n';
        cout << "AI: ";
        cout << check(s) << '\n';
    }
}

signed main() {
//    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T = 1;
//    cin >> T;
    while (T--) {
        solve();
    }
}

 

7-8前世档案

goooogo

思路:将串看成二进制数即可

查看代码
 void solve() {
    int n, m;
    cin >> n >> m;
    for (int i = 0; i < m; ++i) {
        string s;
        cin >> s;
        int ans = 0;
        for (int j = 0; j < n; ++j) {
            if (s[j] == 'y')ans *= 2;
            else ans *= 2, ans ++;
        }
        cout << ans + 1 << '\n';
    }
}

 

7-9抢红包

qwq

思路:用结构体存储信息并排序

查看代码
 #include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;

struct E {
    int s;
    int cnt, id;
    bool operator<(const E &e)const {
        if (s != e.s) return s > e.s;
        if (cnt != e.cnt) return cnt > e.cnt;
        return id < e.id;
    }
};

void solve() {
    int n;
    cin >> n;
    vector<E> ve(n + 1);
    for (int i = 1; i <= n; ++i) {
        ve[i].id = i, ve[i].cnt = 0, ve[i].s = 0;
    }
    for (int i = 1, x; i <= n; ++i) {
        cin >> x;
        for (int j = 0; j < x; ++j) {
            int id, s;
            cin >> id >> s;
            ve[id].s += s, ve[id].cnt ++;
            ve[i].s -= s;
        }
    }
    sort(ve.begin() + 1, ve.end());
    for (int i = 1; i <= n; ++i) {
        cout << ve[i].id << ' ';
        cout << fixed << setprecision(2) <<  ve[i].s * 0.01 << '\n';
    }
}

signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T = 1;
//    cin >> T;
    while (T--) {
        solve();
    }
}

 

7-10红色警报

思路:注意到n并不大,可以考虑暴力点的解法,可以将一个点所在的集合包含的边里删去与该点相连的边后,看该集合是否还是一个集合,这里用并查集来维护

查看代码
 #include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;

vector<int> vis;
vector<int> fa;
int find(int x) {
    if(x != fa[x]) fa[x] = find(fa[x]);
    return fa[x];
}
void mer(int a, int b) {
    a = find(a), b = find(b);
    if(a != b)fa[b] = a;
}
void solve() {
    int n, m;
    cin >> n >> m;
    vis = fa = vector<int> (n);
    vector<vector<int > > ve(n);
    for (int i = 0; i < m; ++i) {
        int u, v;
        cin >> u >> v;
        ve[u].push_back(v),ve[v].push_back(u);
    }
    int k;
    cin >> k;
    vector<int> st(n);
    for (int i = 0, o; i < k; ++i) {
        cin >> o;
        st[o] = 1;
        for (int j = 0; j < n; ++j) fa[j] = j, vis[j] = 0;
        queue<int> q;
        for (auto v:ve[o]) {
            if (!st[v]) q.push(v);
        }
        while (q.size()) {
            auto t = q.front();
            q.pop();
            if (vis[t])continue;
            vis[t] = 1;
            for (auto v:ve[t]) {
                if (st[v] || vis[v])continue;
//                if (o == 0)
                mer(t, v);

                q.push(v);
            }
        }
        set<int> se;
        for (int j = 0; j < n; ++j) {
            if (vis[j]) {

                int v = find (j);
//                if (o == 1) cout << v << ' ';
                se.insert(v);
            }
        }
        if (se.size() <= 1) {
            cout << "City " << o << " is lost.\n";
        } else {
            cout << "Red Alert: City " << o << " is lost!\n";
        }
        if (i == n - 1) {
            cout << "Game Over.";
        }
    }
}

signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T = 1;
//    cin >> T;
    while (T--) {
        solve();
    }
}

 

7-11排座位

qwq

思路:因为朋友的朋友是朋友,用并查集维护朋友集合,并且死对头关系不传递,直接矩阵记录即可,判断每种情况

#include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;

vector<int> fa;
int find(int x) {
    if(x != fa[x]) fa[x] = find(fa[x]);
    return fa[x];
}
void mer(int a, int b) {
    a = find(a), b = find(b);
    if(a != b)fa[b] = a;
}
void solve() {
    int n, m, k;
    cin >> n >> m >> k;
    fa = vector<int> (n + 1);
    vector no(n + 1,vector<int> (n + 1));
    for (int i = 1; i <= n; ++i) fa[i] = i;
    for (int i = 0; i < m; ++i) {
        int u, v, p;
        cin >> u >> v >> p;
        if (p == 1) mer(u, v);
        else no[v][u] = no[u][v] = 1;
    }
    for (int i = 0; i < k; ++i) {
        int u, v;
        cin >> u >> v;
        int uu = find(u), vv = find(v);
        if (uu == vv && !no[u][v]) cout << "No problem\n";
        else if (uu == vv && no[u][v])cout << "OK but...\n";
        else if (uu != vv && !no[u][v])cout << "OK\n";
        else cout <<"No way\n";
    }
}

signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T = 1;
//    cin >> T;
    while (T--) {
        solve();
    }
}

 

7-12这是二叉搜索树吗?

思路:前序序列的特点就是,第一个点为根节点,剩下一部分为左子树,一部分为右子树,并且由于题目给的是二叉搜索树,左子树是小于根节点,右子树是大于等于根节点(镜像相反),那直接递归,判断为一棵二叉搜索树的同时,转换成后续序列

查看代码
 #include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;

int n;
vector<int> ans, pre;
bool isl = true;
void get(int L, int R) {
    if (L > R)return ;
    int r = L + 1, l = R;
    if (isl) {
        while (r <= R && pre[r] < pre[L]) r ++;
        while (l >= L + 1 && pre[l] >= pre[L]) l --;
    } else {
        while (r <= R && pre[r] >= pre[L]) r ++;
        while (l >= L + 1 && pre[l] < pre[L]) l --;
    }
    if (r - l != 1) return ;
    get(L + 1, l), get(r, R);
    ans.push_back(pre[L]);
}
void solve() {
    cin >> n;
    pre = vector<int > (n);
    for (int i = 0; i < n; ++i) {
        cin >> pre[i];
    }

    get(0, n - 1);
    if (ans.size() != n) {
        ans.clear();
        isl = false;
        get(0, n - 1);
    }
    if(ans.size() != n) cout << "NO\n";
    else {
        cout << "YES\n";
        for (int i = 0; i < n; ++i) {
            cout << ans[i];
            if (i < n - 1) cout << ' ';
        }
        cout << '\n';
    }
}

signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T = 1;
//    cin >> T;
    while (T--) {
        solve();
    }
}

 

7-13肿瘤诊断

思路:还还还是并查集,合并6个方向的1,由于我是边读入边合并,只需要合并3个方向即可

查看代码
 #include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;
const int dx[4] = {0,-1}, dy[4] = {-1, 0};
struct E {
    int fa, cnt;
};
vector<E> ve;
int find(int x) {
    if (x != ve[x].fa)
        ve[x].fa = find(ve[x].fa), ve[ve[x].fa].cnt += ve[x].cnt, ve[x].cnt = 0;
    return ve[x].fa;
}
void mer(int a, int b) {
    a = find(a), b = find(b);
    if (a != b){
        ve[b].fa = a;
        ve[a].cnt += ve[b].cnt, ve[b].cnt = 0;
    }
}
void solve() {
    int n, m, l, t;
    cin >> m >> n >> l >> t;
    ve = vector<E>(n * m * l + 5);
    vector g(m, vector<int>(n) );
    for (int i = 0; i < ve.size(); ++i) ve[i].fa = i, ve[i].cnt = 0;
    for (int k = 0; k < l ; ++k) {
        for (int i = 0; i < m; ++i) {
            for (int j = 0; j < n; ++j) {
                bool ok = false;
                if (g[i][j]) ok = true;
                cin >> g[i][j];
                if (g[i][j] == 0)continue;
                int id = k * n * m + i * n + j;
                id = find(id);
                ve[id].cnt += g[i][j];
                if (j > 0 && g[i][j - 1]) {
                    int idd = k * n * m + i * n + j - 1;
                    mer(id, idd);
                }
                if (i > 0 && g[i - 1][j]) {
                    int idd = k * n * m + (i - 1) * n + j;
                    mer(id, idd);
                }
                if (ok) {
                    int idd = (k - 1) * n * m + i * n + j;
                    mer(id, idd);
                }
            }
        }
    }
    set<int>se;
    for (int i = 0; i < ve.size(); ++i) {
        int v = find(i);
        se.insert(v);
    }
    int ans = 0;
    for (auto v:se) {
        int u = find(v);
        if (ve[u].cnt >= t)ans += ve[u].cnt;
    }
    cout << ans;
}

signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T = 1;
//    cin >> T;
    while (T--) {
        solve();
    }
}

 

7-14迎风一刀斩

7-15特殊堆栈

思路:由于需要找中值,这里的值最大1e5,并且还有pop操作(删除),可以用数据结构维护每个值的个数,由区间和来二分中值

查看代码
 #include<bits/stdc++.h>
using namespace std;
//#define int long long
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;

int c[N], n;
int lowbit(int x) {return x & -x;}
void add(int x, int k) {
    while (x <= 1e5) {
        c[x] += k;
        x += lowbit(x);
    }
}
int get(int x) {
    int ans = 0;
    while (x > 0) {
        ans += c[x];
        x -= lowbit(x);
    }
    return ans;
}
int getsum(int l, int r) {
    return get(r) - get(l - 1);
}

void solve() {
    cin >> n;
    stack<int> st;
    for (int i = 0; i < n; ++i) {
        string s;
        cin >> s;
        if (s == "Push") {
            int x;
            cin >> x;
            st.push(x);
            add(x, 1);
        } else if(s == "Pop") {
            if (st.empty()) cout << "Invalid\n";
            else {
                int x = st.top();
                add(x, -1);
                cout << x << '\n', st.pop();
            }
        } else if (s == "PeekMedian") {
            if (st.empty()) cout << "Invalid\n";
            else {
                int cnt = (st.size() + 1) / 2;
                int l = 1, r = 1e5, x;
                while (l <= r) {
                    int mid = ( l + r ) / 2;
                    if( getsum(1, mid) >= cnt ) x = mid, r = mid - 1;
                    else l = mid + 1;
                }
                cout << x << '\n';
            }
        }
    }
}

signed main() {
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T = 1;
//    cin >> T;
    while (T--) {
        solve();
    }
}
posted @ 2024-03-26 22:47  bible_w  阅读(14)  评论(0编辑  收藏  举报