Codeforces Round #498 (Div. 3) 简要题解

[比赛链接]

https://codeforces.com/contest/1006

[题解]

Problem A. Adjacent Replacements

       [算法]

将序列中的所有偶数替换为奇数即可

时间复杂度 : O(N)

[代码]

#include<bits/stdc++.h>
using namespace std;

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - ‘0‘;
    x *= f;
}
int main()
{

        int n;
        read(n);
        for (int i = 1; i <= n; i++)
        {
                int x;
                read(x);
                if (x & 1) printf("%d ",x);
                else printf("%d ",x - 1);
        }
        printf("\n");

        return 0;

}

Problem B. Polycarp‘s Practice

             [算法]

要求k天的和最大化 , 我们不妨将这些数加入一个堆中 , 取出前k大值

构造一组合法的解即可

时间复杂度 : O(NlogN)

[代码]

#include<bits/stdc++.h>
using namespace std;
#define MAXN 2010

int ans[MAXN];

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - ‘0‘;
    x *= f;
}
int main()
{

        int n , k , t = 0 , value = 0;
        static priority_queue< pair<int,int> > q;
        read(n); read(k);
        for (int i = 1; i <= n; i++)
        {
                int x;
                read(x);
                q.push(make_pair(x,i));
        }
        while (t < k)
        {
                value += q.top().first;
                ans[++t] = q.top().second;
                q.pop();
        }
        sort(ans + 1,ans + k + 1);
        printf("%d\n",value);
        for (int i = 1; i <= k - 1; i++) printf("%d ",ans[i] - ans[i - 1]);
        printf("%d\n",n - ans[k - 1]);

        return 0;

}

Problem C. Three Parts of the Array

               [算法]

用Two Pointers扫描求出答案即可

也可以通过std :: set等数据结构求解

时间复杂度 : O(N)

[代码]

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e6 + 10;

long long a[MAXN];

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - ‘0‘;
    x *= f;
}

int main()
{

        long long n;
        read(n);
        for (int i = 1; i <= n; i++) read(a[i]);
        long long l = 1 , r = n;
        long long s1 = 0 , s2 = 0 , ans = 0;
        while (l <= r)
        {
                if (s1 < s2)
                {
                        s1 += a[l++];
                        if (s1 == s2) ans = s1;
                }    else if (s2 < s1)
                {
                        s2 += a[r--];
                        if (s1 == s2) ans = s1;
                } else
                {
                        if (l == r) break;
                        s1 += a[l++];
                        s2 += a[r--];
                        if (s1 == s2) ans = s1;
                }
        }
        printf("%I64d\n",ans);

        return 0;

}

Problem D. Two Strings Swaps

                      [算法]

枚举字符串的前[n/2]个字符 ([x]表示向下取整) ,

如果字符串a和字符串b的第i个字符和第(n - i + 1)个字符共有4个不同的字符 , 显然对答案产生2的贡献

如果有3个不同字符 , 当字符串a的第i个字符和第(n - i + 1)个字符相同 , 则对答案产生2的贡献 , 否则对答案产生1的贡献

如果有2个不同字符 , 如果第a的第i个字符出现次数不为2 , 则对答案产生1的贡献

当字符串长度为奇数时 , 若字符串a的第(n + 1) / 2和字符串b的第(n + 1) / 2个字符不相等 , 则对答案产生1的贡献

[代码]

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 10;

int n , ans;
char a[MAXN],b[MAXN];

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - ‘0‘;
    x *= f;
}
int main()
{

        scanf("%d",&n);
        scanf("%s%s",a + 1,b + 1);
        for (int i = 1; i <= n / 2; i++)
        {
                map< char,int > mp;
                mp.clear();
                mp[a[i]]++;
                mp[a[n - i + 1]]++;
                mp[b[i]]++;
                mp[b[n - i + 1]]++;
                if ((int)mp.size() == 4) ans += 2;
                if ((int)mp.size() == 3)
                {
                        if (a[i] == a[n - i + 1]) ans += 2;
                        else ans++;
                }
                if ((int)mp.size() == 2)
                {
                        if (mp[a[i]] != 2)
                            ans++;
                }
        }
        if ((n & 1) && a[n / 2 + 1] != b[n / 2 + 1]) ans++;
        printf("%d\n",ans);

        return 0;

}

Problem E. Military Problem

                           [算法]

不妨先求出整棵树的DFS序 , 记为Dfn[]

然后 , 我们用Pos[i]表示DFS序为i的节点

对于询问(ui , ki) ,  显然 , 答案为Pos[Dfn[ui] - 1 + k]

时间复杂度 : O(N)

[代码]

#include<bits/stdc++.h>
using namespace std;
const int MAXN = 2e5 + 10;

int n , q , timer;
int size[MAXN],ans[MAXN],depth[MAXN],dfn[MAXN];
vector< int > G[MAXN];

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - ‘0‘;
    x *= f;
}
inline void dfs(int u)
{
        size[u] = 1;
        dfn[u] = ++timer;
        ans[timer] = u;
        for (unsigned i = 0; i < G[u].size(); i++)
        {
                depth[G[u][i]] = depth[u] + 1;
                dfs(G[u][i]);
                size[u] += size[G[u][i]];
        }
}

int main()
{

        read(n); read(q);
        for (int i = 2; i <= n; i++)
        {
                int x;
                read(x);
                G[x].push_back(i);
        }
        dfs(1);
        while (q--)
        {
                int u , k;
                read(u); read(k);
                if (size[u] < k)
                {
                        printf("-1\n");
                        continue;
                }
                printf("%d\n",ans[dfn[u] + k - 1]);
        }

        return 0;

}

Problem F. Xor Paths

                             [算法]

显然 , 所有的路径长度都为(n + m - 1)

考虑使用Meet-In-The-Middle( 中途相遇法 )

第一遍DFS求出前(n + m - 1)步 , 每个位置上出现的异或和情况数

第二遍DFS求出后(n + m) / 2步 , 根据第一遍DFS求出的情况数统计答案

时间复杂度 : O(2 ^ ((n + m - 2) / 2) * (n + m - 2) / 2)

[代码]

#include<bits/stdc++.h>
using namespace std;
#define MAXN 25
#define MAXS 100005

int n , m;
long long a[MAXN][MAXN];
long long val , ans = 0;
map< long long,int > cnt[MAXN][MAXN];

template <typename T> inline void chkmax(T &x,T y) { x = max(x,y); }
template <typename T> inline void chkmin(T &x,T y) { x = min(x,y); }
template <typename T> inline void read(T &x)
{
    T f = 1; x = 0;
    char c = getchar();
    for (; !isdigit(c); c = getchar()) if (c == ‘-‘) f = -f;
    for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - ‘0‘;
    x *= f;
}
inline bool valid(int x,int y)
{
        return x >= 1 && x <= n && y >= 1 && y <= m;
}
inline void dfs1(int x,int y,int step,long long k)
{
        if (step == (n + m - 1) / 2)
        {
                cnt[x][y][k]++;
                return;
        }
        if (valid(x + 1,y)) dfs1(x + 1,y,step + 1,k ^ a[x + 1][y]);
        if (valid(x,y + 1)) dfs1(x,y + 1,step + 1,k ^ a[x][y + 1]);
}
inline void dfs2(int x,int y,int step,long long k)
{
        if (step == (n + m) / 2)
        {
                if (valid(x,y - 1)) ans += cnt[x][y - 1][val ^ k];
                if (valid(x - 1,y)) ans += cnt[x - 1][y][val ^ k];
                return;
        }
        if (valid(x - 1,y)) dfs2(x - 1,y,step + 1,k ^ a[x - 1][y]);
        if (valid(x,y - 1)) dfs2(x,y - 1,step + 1,k ^ a[x][y - 1]);
}

int main()
{

        read(n); read(m); read(val);
        for (int i = 1; i <= n; i++)
        {
                for (int j = 1; j <= m; j++)
                {
                        read(a[i][j]);
                }
        }
        if (n == 1 && m == 1)
        {
                if (a[1][1] == val) printf("1\n");
                else printf("0\n");
                return 0;
        }
        dfs1(1,1,1,a[1][1]);
        dfs2(n,m,1,a[n][m]);
        printf("%I64d\n",ans);

        return 0;

}

 

原文地址:https://www.cnblogs.com/evenbao/p/9734944.html

时间: 2024-08-29 23:31:26

Codeforces Round #498 (Div. 3) 简要题解的相关文章

Codeforces Round #483 (Div. 1) 简要题解

来自FallDream的博客,未经允许,请勿转载,谢谢. 为了证明一下我又来更新了,写一篇简要的题解吧. 这场比赛好像有点神奇,E题莫名是道原题,导致有很多选手直接过掉了(Claris 表演24s过题).然而D题比E题要难一些,分还少. A. Finite or not? 先把\(\frac{p}{q}\)约成最简分数,然后就是要判断是否\(q\)的所有质因数都是\(b\)的质因数. 每次取\(g=gcd(b,q)\),并尽可能的让\(q\)除\(g\),最后判断\(q\)是否是1即可. 还有一

Codeforces Round #619 (Div. 2) 简要题解

A:只要每个位置都满足a[i] = c[i]或b[i] = c[i]即可. int main() { int t; scanf("%d", &t); while(t --) { char a[110], b[110], c[110]; scanf("%s%s%s", a, b, c); int n = strlen(a), tag = 1; for(int i = 0; i < n; i ++) { if(a[i] == c[i] || b[i] ==

# Codeforces Round #529(Div.3)个人题解

Codeforces Round #529(Div.3)个人题解 前言: 闲来无事补了前天的cf,想着最近刷题有点点怠惰,就直接一场cf一场cf的刷算了,以后的题解也都会以每场的形式写出来 A. Repeating Cipher 传送门 题意:第一个字母写一次,第二个字母写两次,依次递推,求原字符串是什么 题解:1.2.3.4,非常明显的d=1的等差数列,所以预处理一个等差数列直接取等差数列的每一项即可 代码: #include<bits/stdc++.h> using namespace s

Codeforces Round #531 (Div. 3) ABCDE题解

Codeforces Round #531 (Div. 3) 题目总链接:https://codeforces.com/contest/1102 A. Integer Sequence Dividing 题意: 给一个数n,然后要求你把1,2.....n分为两个集合,使得两个集合里面元素的和的差的绝对值最小. 题解: 分析可以发现,当n%4==0 或者 n%3==0,答案为0:其余答案为1.之后输出一下就好了. 代码如下: #include <bits/stdc++.h> using name

Codeforces Round #540 (Div. 3) 部分题解

Codeforces Round #540 (Div. 3) 题目链接:https://codeforces.com/contest/1118 题目太多啦,解释题意都花很多时间...还有事情要做,就选一些题来写吧. B. Tanya and Candies 题意: 在n个数中任意删去一个,如果这个数被删去后,剩余数的奇数和以及偶数和相等,那么就定义这个数为"好数".现在问这n个数中有多少个“好数”. 题解: 预处理出奇数前缀和.偶数前缀和,删去一个数后所有的奇数位置和 就为前面的奇数和

Codeforces Round #632 (Div. 2) 部分题解

目录 Codeforces Round #632 (Div. 2) A. Little Artem B. Kind Anton C. Eugene and an array D. Challenges in school №41 F. Kate and imperfection Codeforces Round #632 (Div. 2) A. Little Artem 题意:略. 分析:构造这样的图形: BWW...W BWW...W BBB...B #include <bits/stdc++

Codeforces Round #Pi (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/567 听说Round #Pi的意思是Round #314... A. Lineland Mail time limit per test:3 seconds memory limit per test:256 megabytes All cities of Lineland are located on the Ox coordinate axis. Thus, each city is associated with it

Codeforces Round #200 (Div. 2) (ABCDE题解)

比赛链接:http://codeforces.com/contest/344 A. Magnets time limit per test:1 second memory limit per test:256 megabytes Mad scientist Mike entertains himself by arranging rows of dominoes. He doesn't need dominoes, though: he uses rectangular magnets inst

Codeforces Round #250 (Div. 2) (ABCD题解)

比赛链接:http://codeforces.com/contest/433 A. Kitahara Haruki's Gift time limit per test:1 second memory limit per test:256 megabytes Kitahara Haruki has bought n apples for Touma Kazusa and Ogiso Setsuna. Now he wants to divide all the apples between th