Codeforces Round 918 (Div. 4)(补题AK)(c/c++)

Codeforces Round 918 (Div. 4)(补题AK)其实这次比赛没打算打的,看看题算了,但我的牛魔舍友在那bark,bark的叫,所以我就写了一道D题

A - Odd One Out

思路:简单题,if-else练习题

AC Code

#include 
#include 
#include 
#include 
#include 
#include 
#define ll long long
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define maxn (ll)(2e5 + 5000)
using namespace std;
// set::iterator it;
map<int, int> w;
int main(void)
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        int a, b, c;
        w.clear();
        scanf("%d%d%d", &a, &b, &c);
        w[a]++;
        w[b]++;
        w[c]++;
        if (w[a] == 1)
        {
            printf("%d\n", a);
        }
        else if (a == c)
        {
            printf("%d\n", b);
        }
        else
        {
            printf("%d\n", c);
        }
    }

    return 0;
}

B - Not Quite Latin Square

思路:读入一个3*3的矩阵,每个都应出现3次,把少的那个输出即可

AC Code

#include 
#include 
#include 
#include 
#include 
#include 
#define ll long long
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define maxn (ll)(2e5 + 5000)
using namespace std;
// set::iterator it;
char a[10][10];
map<char, int> cnt;
int main(void)
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        cnt.clear();
        f(i, 0, 2)
        {
            scanf("%s", a[i]);
        }
        char tmp = 'A';
        f(i, 0, 2)
        {
            f(j, 0, 2)
            {
                cnt[a[i][j]]++;
            }
        }
        f(i, 0, 2)
        {
            if (cnt['A' + i] < 3)
            {
                printf("%c\n", 'A' + i);
                break;
            }
        }
    }

    return 0;
}

C - Can I Square?

思路:简单的模拟,注意sqrt的精度即可

AC Code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define ll long long
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define maxn (ll)(2e5 + 5000)
using namespace std;
// set::iterator it;
ll a;
map<ll, int> cnt;

int main(void)
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        int n;
        scanf("%d", &n);
        ll sum = 0;
        ll tmp;
        f(i, 1, n)
        {
            scanf("%lld", &tmp);
            sum += tmp;
        }
        ll w = sqrt(sum);
        int flag = 0;
        for (ll i = w - 1; i <= w + 1; i++)
        {
            if (i < 0)
            {
                continue;
            }
            if (i * i == sum)
            {
                printf("YES\n");
                flag = 1;
                break;
            }
        }
        if (flag == 0)
        {
            printf("NO\n");
        }
    }

    return 0;
}

D - Unnatural Language Processing

思路:简单观察一下,得出规律即可

AC Code

#include 
#include 
#include 
#include 
#include 
#include 
#define ll long long
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define maxn (ll)(2e5 + 5000)
using namespace std;
// set::iterator it;
char a[maxn];
int main(void)
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        int n;
        scanf("%d", &n);
        getchar();
        f(i, 1, n)
        {
            scanf("%c", &a[i]);
        }
        f(i, 1, n)
        {
            if (a[i] == 'b' || a[i] == 'c' || a[i] == 'd')
            {
                printf("%c", a[i]);
                i++;
                if (i == n)
                {
                    printf("%c\n", a[i]);
                    break;
                }
                printf("%c", a[i]);
                i++;
                if (i == n)
                {
                    printf("%c\n", a[i]);
                    break;
                }
                if (a[i + 1] == 'b' || a[i + 1] == 'c' || a[i + 1] == 'd')
                {
                    printf("%c", a[i]);
                    printf(".");
                }
                else
                {
                    printf(".");
                    i--;
                }
            }
        }
    }

    return 0;
}

E - Romantic Glasses

思路:其实就是所有奇数乘一个负一就行了

AC Code

#include 
#include 
#include 
#include 
#include 
#include 
#define ll long long
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define maxn (ll)(2e5 + 5000)
using namespace std;
// set::iterator it;
int a[maxn] = {0};
ll pre[maxn] = {0};
map<ll, int> w;
int main(void)
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        int n;
        scanf("%d", &n);
        int flag = 0;
        w.clear();
        f(i, 1, n)
        {
            scanf("%d", &a[i]);
            if (i % 2 == 1)
            {
                a[i] *= (-1);
            }
            pre[i] = pre[i - 1] + a[i];
        }
        f(i, 1, n)
        {
            w[pre[i]]++;
            if (w[pre[i]] >= 2 || pre[i] == 0)
            {
                flag = 1;
                break;
            }
        }

        if (flag == 1)
        {
            printf("YES\n");
        }
        else
        {
            printf("NO\n");
        }
    }

    return 0;
}

F - Greetings

思路:先将左端点排升序,保证每一人都只会被后面序列的人撞到,其实就是求后面b[j]>b[i]的个数,也就是求逆序对的个数,把板子代入即可(排序问题的衍生问题)

AC Code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define ll long long
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define maxn (ll)(2e5 + 5000)
using namespace std;
// set::iterator it;
pair<int, int> a[maxn];
int b[maxn];
int tmp[maxn];
ll merge_sort(int q[], int l, int r)
{
    if (l >= r)
    {
        return 0;
    }
    int mid = (l + r) >> 1; // 二分区间

    ll res = merge_sort(q, l, mid) + merge_sort(q, mid + 1, r);
    // 归并
    int i = l, j = mid + 1, k = 0;

    while (i <= mid && j <= r)
    {
        if (q[i] <= q[j])
            tmp[k++] = q[i++]; // 前面的排序正常,注意`=` 说明不是逆序对
        else
        {
            res += mid - i + 1;
            tmp[k++] = q[j++];
        }
    }
    // 扫尾工作
    while (i <= mid)
    {
        tmp[k++] = q[i++];
    }
    while (j <= r)
    {
        tmp[k++] = q[j++];
    }

    for (int i = l, j = 0; i <= r; i++, j++)
    {
        q[i] = tmp[j];
    }

    return res;
}

int main(void)
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        int n;
        scanf("%d", &n);
        f(i, 1, n)
        {
            scanf("%d%d", &a[i].first, &a[i].second);
        }
        sort(a + 1, a + n + 1);
        f(i, 1, n)
        {
            b[i] = a[i].second;
        }
        ll ans = merge_sort(b, 1, n);
        printf("%lld\n", ans);
    }

    return 0;
}

G - Bicycles

思路:这应该就是最短路的板子题,我就学了一下迪杰斯特拉(Dijkstra)算法,也能做出来,然后不得不说的是这个填表的过程,总给我一种dp的感觉(哦,还有一个事情,千万不要用大顶堆当消愁)

AC Code

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define ll long long
#define int long long // 非常犹豫,到底要不要用这个,不过有句话说的好,十年oi一场空 不开long long见祖宗啊!!!
#define f(i, s, e) for (int i = s; i <= e; i++)
#define ff(i, s, e) for (int i = s; i >= e; i--)
#define maxn (ll)(2e5 + 5000)
using namespace std;
const ll linf = 5e18;
const ll N = 1100;
struct node
{
    int num; // 要去的城市
    int dis; // 距离
    int s;   // 拥有的自行车系数
    bool operator>(const node &other) const
    {
        return dis > other.dis; // 为什么会有人用大顶堆,笑死了,记得要用小顶堆啊
    }
};
struct node tmp, fuck;
int n, m;
int dis[N][N]; // 到达i点,且拥有自行车系数j的最短距离(这个真的有一种DP即视感,这真的很像定义状态)
int vis[N][N]; // 标记
int cost[N];   // dis*s;
vector<node> temp[N];
void dijkstra(int s)
{
    f(i, 1, n)
    {
        f(j, 0, 1000)
        {
            dis[i][j] = linf; // 初始成无穷大(好像背包dp里有一种就要初始成无穷大)
        }
    }
    priority_queue<node, vector<node>, greater<node>> q;
    q.push({s, 0, cost[1]});
    dis[s][cost[1]] = 0;
    while (!q.empty())
    {
        tmp = q.top();
        int x = tmp.num; // 所在地
        int y = tmp.s;   // 拥有的自行车系数
        q.pop();
        if (vis[x][y] == 1)
        {
            continue;
        }
        vis[x][y] = 1;
        f(i, 0, (int)temp[x].size() - 1)
        {
            fuck = temp[x][i];
            int len = temp[x][i].dis;
            int next = temp[x][i].num;      // 目标地
            int nexts = min(y, cost[next]); // 到达目的地之后所拥有的自行车系数
            if (dis[next][nexts] > dis[x][y] + len * y)
            {
                dis[next][nexts] = dis[x][y] + len * y; // 卧槽,这个填表的感觉,dp,蒸馍哪里都是尼
                q.push({next, dis[next][nexts], nexts});
            }
        }
    }
}
signed main(void)
{
    int t;
    scanf("%lld", &t);
    while (t--)
    {
        scanf("%lld%lld", &n, &m);
        f(i, 1, n)
        {
            temp[i].clear(); // 二维vetor的清空,一定要记得初始化啊啊啊!!!
            f(j, 1, 1001)
            {
                vis[i][j] = 0;
            }
        }
        f(i, 1, m)
        {
            int u, v, dist;
            scanf("%lld%lld%lld", &u, &v, &dist);
            // 对于喜欢从1开始的人来说,vector有点......
            temp[u].push_back({v, dist, 0}); // 简便写法;
            temp[v].push_back({u, dist, 0});
        }
        f(i, 1, n)
        {
            scanf("%lld", &cost[i]);
        }
        dijkstra(1);
        int ans = linf;
        f(i, 0, 1000)
        {
            ans = min(ans, dis[n][i]); // 比较
        }
        printf("%lld\n", ans);
    }

    return 0;
}

总结:这个比赛毕竟是cf的最简单的,难得有一次能补完题,这就是今年最后一篇博客啦

你可能感兴趣的:(c语言,c++,算法,数据结构)