Hello 2019题解

Hello 2019题解

题解 CF1097A 【Gennady and a Card Game】

map大法好qwq

枚举每一个的第\(1,2\)位判是否与给定的重复即可

# include <bits/stdc++.h>
std::map<char, int> m1, m2;
int main()
{
    std::string s[6], str;
    std::cin >> str;
    for(int i = 1; i <= 5; i++)
        std::cin >> s[i], m1[s[i][0]] = 1, m2[s[i][1]] = 1;
    if(m1[str[0]] || m2[str[1]])
        return printf("YES\n") * 0;
    printf("NO\n");
    return 0;
}

题解 CF1097B 【Petr and a Combination Lock】

\(dfs\)入门题,下一个

枚举每一个是正还是负,最后判能不能被\(360\)整除即可
时间复杂度\(O(2^n)\)


# include <bits/stdc++.h>

int n, flag, a[20], used[20];

inline void check()
{
    int sum = 0;
    for(int i = 1; i <= n; i++)
        sum += a[i] * (used[i] ? (-1) : 1);
    if(sum % 360 == 0)
        flag = 1;
}

void dfs(int x)
{
    if(x == n + 1)
        return (void) (check());
    dfs(x + 1);
    used[x] = 1;
    dfs(x + 1);
    used[x] = 0;
}

int main()
{
    scanf("%d", &n);
    for(int i = 1; i <= n; i++)
        scanf("%d", &a[i]);
    dfs(1);
    printf(flag ? "YES" : "NO");
    return 0;
}

题解 CF1097C 【Yuhao and a Parenthesis】

~~说起Yuhao,我就不得不提@BlueCat,想起了他旋转**的情景,明年,中美,两开花,关注~~

对于每个括号序列,我们都用栈预处理出它不能配对的部分

等等?什么叫不能配对的部分?

比如说序列\()())\),\())\)就是它不能配对的部分

然后把这个部分取反

就得到了如果要把这个序列弄成正确的需要的最简序列\(x_i\)

显然这个部分要放在当前串的前面或后面

但是我们有些时候发现这东西是假的

比如这个序列\())))((((\),它的匹配序列是\((((())))\),很明显放前或后都不行,那么这个串就废了

如果这个串没废,就把\(x_i\)的计数累加\(1\)

然后我们枚举每一个\(x_i\),将\(ans\)累加上\(\min{x_i,x_i取反}\)(取反只把一个括号序列中'('变成')',反之亦然)

注意这里有一个特判,如果有一个串本来就是好的,那么统计答案时,由于空串的反串还是空串,所以答案会算两次

所以要特判出好串的个数\(cnt\)

最后输出\(ans/2+cnt/2\)即可(下取整)

#include <bits/stdc++.h>

const int MaxN = 100010, MaxM = 500010;

std::string s[MaxN], str[MaxN];
std::map<std::string, int> m;

inline std::string change(std::string s)
{
    int len = s.length();
    std::string tmp = "";
    for (int i = 0; i < len; i++)
        tmp += ((s[i] == '(') ? ')' : '(');
    return tmp;
}

inline int check1(std::string s)
{
    std::stack<char> st;
    int len = s.length();
    for (int i = 0; i < len; i++)
    {
        if (s[i] == '(')
            st.push('(');
        else if (s[i] == ')' && st.empty())
            return 0;
        else
            st.pop();
    }
    return 1;
}

inline void check(int x, std::string s)
{
    std::vector<char> st;
    int len = s.length();
    for (int i = 0; i < len; i++)
    {
        if (st.empty())
        {
            st.push_back(s[i]);
            continue;
        }
        if (s[i] == '(')
            st.push_back('(');
        else if (s[i] == ')' && st.back() == '(')
            st.pop_back();
        else if (s[i] == ')' && st.back() == ')')
            st.push_back(')');
    }
    std::string tmp = "";
    for (int i = 0; i < st.size(); i++)
        tmp += ((st[i] == '(') ? ')' : '(');
    if (check1(tmp + s) || check1(s + tmp))
        ++m[tmp];
    //  std::cout << " " << s << " " << tmp << "\n";
}

int main()
{
    int n, ans = 0;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++)
        std::cin >> s[i], check(i, s[i]);
    for (std::map<std::string, int>::iterator it = m.begin(); it != m.end(); ++it)
    {
        if (it->first == "")
            continue;
        ans += std::min(it->second, m[change(it->first)]);
    }
    printf("%d\n", (ans / 2) + (m[""] / 2));
    return 0;
}

转载于:https://www.cnblogs.com/little-sun0331/p/10225794.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对不起,由于我是一个文本交互的模型,我无法提供图像内容或直接链接到具体的题解或解决方案。但是,我可以帮你理解CSP-J2019公交换乘问题的基本概念和解决策略,这通常涉及到数据结构、图论以及算法设计。 CSP-J2019中的公交换乘问题可能是一个典型的旅行商问题(Traveling Salesman Problem, TSP)变种,或者是寻找最优路径的问题,其中涉及到公交网络中不同站点之间的最短路径或最少换乘次数。解决此类问题通常需要使用动态规划、贪心算法或者一些启发式搜索算法,比如A*搜索或Dijkstra算法。 如果你需要了解题目的基本思路,可能会这样操作: 1. 建立一个图,节点代表公交站点,边代表两个站点之间的路线及其长度或换乘次数。 2. 对于每个节点,计算从起点到所有其他节点的最短路径,形成一个邻接矩阵或邻接表。 3. 使用动态规划方法,例如记忆化搜索,尝试所有可能的路径,每次选择当前未访问节点中距离最近的一个,直到遍历完所有节点并回到起点,记录下总的距离或换乘次数。 4. 为了优化,可以考虑使用启发式搜索策略,如用估算的总距离作为启发信息,优先探索看起来更优的路径。 如果你对具体解法有疑问,或者想了解某个步骤的详细操作,请告诉我,我会尽力解释。至于详细的题解,建议你查阅相关的代码库、论坛帖子或在线教程,它们通常会有文字描述和步骤示例。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值