Wust周赛三

A.Suits

分析:模拟题

注意:C++中min函数只能比较两个数之间的大小

          min(a,b,c)  (x)  -------->min(a,min(b,c)) 

#include <bits/stdc++.h>
using namespace std;
int a, b, c, d, e, f;
long long sum;
int min1, min2;
int main()
{
    cin >> a >> b >> c >> d >> e >> f;
    if (e <= f)
    {
        min1 = min(b, min(c, d));
        sum += min1 * f;
        b -= min1, c -= min1, d -= min1;
        if (d > 0)
        {
            min2 = min(a, d);
            sum += min2 * e;
        }
    }
    else if (e > f)
    {
        min1 = min(a, d);
        sum += min1 * e;
        a -= min1, d -= min1;
        if (d > 0)
        {
            min2 = min(b, min(c, d));
            sum += min2 * f;
        }
    }
    cout << sum << endl;
    return 0;
}

B.Blocks

分析:递推。因为题目中不需要求最小次数,我们可以逐个枚举每个位置的方块,每个位置只有操作和不操作两种可能。

#include <bits/stdc++.h>
using namespace std;
int n;
void update(char &c){//转换函数
    if (c == 'W') c = 'B';
    else c = 'W';
}
bool check(string s, char c){//判断合法
    vector<int> ans;//存储操作
    for (int i = 0; i < n - 1; i ++ ){//n-1次操作
        if (s[i] != c){//不相等,就转换s[i]与s[i+1]
            update(s[i]);
            update(s[i + 1]);
            ans.push_back(i);//把操作装入容器
        }
    }
    if (s[n - 1] != s[0]) return false;//头尾元素不相等即不合法
    cout << ans.size() << '\n';//输出操作数
    for (auto x : ans)//输出每个操作
        cout << x + 1 << ' ';//注意,操作是从1开始的
    return true;
}
int main()
{
    cin >> n;
    string s;
    cin >> s;
    if (!check(s, 'W') && !check(s, 'B'))//当全变白不行并且全变黑不行,无解
        printf("-1\n");
    return 0;
}

C.Azamon Web Services

分析: 1.贪心地想:字符串最小肯定是让字典序最小的字母尽量靠前

            2.在让字典序最小的字母尽量靠前的前提下,让字典序大的字母越靠后越优

#include <bits/stdc++.h>
using namespace std;
typedef pair<char, int> pci;
int n;
set<pci> p;//用set维护一个有序序列,默认为升序
int main()
{
    int T;
    cin >> T;
    while (T--)
    {
        p.clear();//每次 操作前初始化
        string s, t;
        cin >> s >> t;
        for (int i = 0; i < s.size(); i++)
            p.insert({s[i], i});
        for (auto &i : s)
        {
            char mn = (*p.begin()).first;
            if (i == mn)
                p.erase(p.begin());
            else
            {
                auto it = --p.lower_bound({mn, int(1e9)});//返回大于等于mn的最小的数的前一个数的迭代器
                swap(i, s[(*it).second]);
                break;
            }
        }
        if (s < t)
            cout << s << '\n';
        else
            puts("---");
    }
    return 0;
}

D.Shawarma Tent

 分析:

本题如果没有 帐篷不能摆放在学校所在地 这一条件,那么就很好想了:我们直接 把帐篷放在学校 不就行了吗?这样人人都能买帐篷了。

可是现在不能直接把帐篷放在学校,其实也很好想。我们直接把帐篷放在学校的上、下、左、右(四周) 就可以了。请看下面这张图:

在这张图中,我们假设帐篷分别在 1,2,3,4四个点上。那么:

1号帐篷将覆盖 区域 #1的所有学生,即覆盖了位于学校左边的所有学生;

2 号帐篷将覆盖 区域 #2的所有学生,即覆盖了位于学校右边的所有学生;

3 号帐篷将覆盖 区域 #3的所有学生,即覆盖了位于学校上边的所有学生;

44 号帐篷将覆盖 区域 #4的所有学生,即覆盖了位于学校下边的所有学生。

我们如果随意移动 1,2,3,4号帐篷的任意一个,就会发现,再也没有其他摆法能像这种摆法一样,覆盖这么广的区域了!

我们只需要在读入时分别统计 1,2,3,4号帐篷 能否覆盖到第 i 个学生。若能,在对应帐篷的 统计变量 上增加 1

最后,输出这四个帐篷统计变量的 最大值,并输出能覆盖到最多学生的帐篷的坐标就可以了!

#include <bits/stdc++.h>
using namespace std;
int n, sx, sy;
int maxx, ans1, ans2, ans3, ans4;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> sx >> sy;
    while (n--)
    {
        int x, y;
        cin >> x >> y;
        if (x < sx)
            ans1++;
        if (x > sx)
            ans2++;
        if (y < sy)
            ans3++;
        if (y > sy)
            ans4++;
    }
    maxx = max(max(ans1, ans2), max(ans3, ans4));
    cout << maxx << '\n';
    if (maxx == ans1)
        cout << sx - 1 << ' ' << sy;
    else if (maxx == ans2)
        cout << sx + 1 << ' ' << sy;
    else if (maxx == ans3)
        cout << sx << ' ' << sy - 1;
    else if (maxx == ans4)
        cout << sx << ' ' << sy + 1;
    return 0;
}

E.Cut and Paste

分析: 

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1e9 + 7;
string s;
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    int T;
    cin >> T;
    while (T--)
    {
        int x;
        cin >> x >> s;
        ll ans = s.size();
        for (int i = 0; i < x; i++)
        {
            if (s.size() >= x)
            {
                ans = (ans + ((ans - i - 1 + mod) % mod) * (s[i] - '1')) % mod;
            }
            else
            {
                if (s[i] == '2')
                    s += s.substr(i + 1);
                if (s[i] == '3')
                    s += s.substr(i + 1) + s.substr(i + 1);
                ans = s.size();//更新ans数组
            }
        }
        cout << ans << endl;
    }
    return 0;
}

F.Portals

分析:DP 

#include <bits/stdc++.h>
using namespace std;
const int M = 5e3 + 10;
const int inf = 0x3f3f3f3f;
int a[M], b[M], c[M], f[M][M], t[M];
int n, m, k;
struct node
{
    int t, c;
} l[M];
bool cmp(node x, node y)
{
    return x.t < y.t;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> m >> k;
    for (int i = 1; i <= n; i++)
    {
        cin >> a[i] >> b[i] >> c[i];
        t[i] = i;//初始化最晚控制时间
    }
    while (m--)
    {
        int u, v;
        cin >> u >> v;
        t[v] = max(t[v], u);//更改最晚控制时间
    }
    for (int i = 1; i <= n; i++)
    {
        l[i].t = t[i];
        l[i].c = c[i];
    }
    sort(l + 1, l + 1 + n, cmp);//按照最晚控制时间升序排序
    for (int j = 0; j <= k; j++)
        f[0][j] = 0;//初始化
    for (int j = k + 1; j < M; j++)
        f[0][j] = -inf;//初始化成极小值
    int idx = 1;//指向当前可控制的城堡
    for (int i = 1; i <= n; i++)
    {
        for (int j = 0; j < M; j++)
            f[i][j] = -inf;
        for (int j = a[i]; j < M; j++)
            f[i][j + b[i]] = max(f[i][j + b[i]], f[i - 1][j]);
        while (idx <= n && l[idx].t == i)
        {
            for (int j = 0; j < M - 1; j++)
                f[i][j] = max(f[i][j], f[i][j + 1] + l[idx].c);
            idx++;
        }
    }
    int ans = -1;
    for (int j = 0; j < M; j++)
        ans = max(ans, f[n][j]);
    cout << ans << '\n';
    return 0;
}

G.Beingawesomeism

 

#include <iostream>
using namespace std;
int t, n, m;
char a[65][65];
int main()
{
    cin >> t;
    while (t--)
    {
        cin >> n >> m;
        int sum = 0, f = 4, b1 = 0, b2 = 0, b3 = 0, b4 = 0, sum2 = 0;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
            {
                cin >> a[i][j];
                if (a[i][j] == 'A')
                    sum++;
                else
                    sum2++;
                if (((i == 1 && j == 1) || (i == 1 && j == m) || (i == n && j == 1) || (i == n && j == m)) && a[i][j] == 'A')
                    f = 2; // 角落
                if ((i == 1 || j == 1 || i == n || j == m) && a[i][j] == 'A')
                    f = min(f, 3); // 边上点
                if (i == 1 && a[i][j] == 'A')
                    b1++; // 边上线
                if (i == n && a[i][j] == 'A')
                    b2++;
                if (j == 1 && a[i][j] == 'A')
                    b3++;
                if (j == m && a[i][j] == 'A')
                    b4++;
            }
        for (int i = 1; i <= n; i++)
        {
            int num = 0;
            for (int j = 1; j <= m; j++)
                if (a[i][j] == 'A')
                    num++;
            if (num == m)
                f = 2;
        } // 中间线判断
        for (int j = 1; j <= m; j++)
        {
            int num = 0;
            for (int i = 1; i <= n; i++)
                if (a[i][j] == 'A')
                    num++;
            if (num == n)
                f = 2;
        }
        if (b1 == m || b2 == m || b3 == n || b4 == n)
            f = 1;
        if (sum == 0)
            cout << "MORTAL\n"; // 全为P
        else if (sum2 == 0)
            cout << "0\n"; // 全为A
        else
            cout << f << endl; // 否则输出
    }
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值