Codeforces Round #790 (Div. 4)(A ~ H2 全解析)

题目来源

A Lucky?(模拟)

点此进入题面

题意:

在这里插入图片描述
思路:

模拟

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>

using namespace std;

//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 1e5 + 10;
int n, a[N];


signed main()
{
        int t; cin>>t;
        while(t--)
        {
                string s; cin>>s;
                string s1 = s.substr(0, 3), s2 = s.substr(3);

                if((s1[0] - '0') + s1[1] - '0'+ s1[2] - '0' == (s2[0] - '0') + (s2[1] - '0') + (s2[2] - '0')) puts("YES");
                else puts("NO");
        }

        return 0;
}

B Equal Candies(贪心)

点此进入题面

题意:
在这里插入图片描述

思路:

贪心

最后每个盒子里糖的数量一定是 min(ai)

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>

using namespace std;

//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 1e2 + 10;
int n, a[N];


signed main()
{
        int t; cin>>t;
        while(t--)
        {
                cin>>n;
                int mn = 0x3f3f3f3f;
                for(int i=1; i<=n; ++i) cin>>a[i], mn = min(mn, a[i]);
                int sum = 0;
                for(int i=1; i<=n; ++i)
                {
                        if(a[i]==mn) continue;
                        sum += a[i] - mn;
                }
                cout<<sum<<'\n';
        }

        return 0;
}

C Most Similar Words(暴力)

点此进入题面

题意:
在这里插入图片描述

思路:
在这里插入图片描述

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>

using namespace std;

//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 1e5 + 10;
int n, a[N];
string s[100];

int cal(string a, string b)
{
        int step = 0;
        for(int i=0; i<a.size(); ++i)
        {
                int t = abs(a[i] - b[i]);
                step += t;
        }
        return step;
}

signed main()
{
        int t; cin>>t;
        while(t--)
        {
                int m; cin>>n>>m;
                for(int i=1; i<=n; ++i)
                {
                        cin>>s[i];
                }
                int mn = 0x3f3f3f3f;
                for(int i=1; i<=n-1; ++i)
                {
                        for(int j=i+1; j<=n; ++j)
                        {
                                int tmp = cal(s[i], s[j]);
                                mn = min(mn, tmp);
                        }
                }
                cout<<mn<<'\n';
        }

        return 0;
}

D X-Sum(模拟)

点此进入题面

题意:
在这里插入图片描述
在这里插入图片描述

思路:
在这里插入图片描述

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>

using namespace std;

//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 1e5 + 10;
int n, m, a[N];
int g[300][300];
bool st[300][300];
int dx[] = {-1, -1, 1, 1}, dy[] = {1, -1, 1, -1};

bool jud(int x, int y)
{
        if(x<1 || x>n || y<1 || y>m) return true;
        return false;
}

int cal(int x, int y)
{
        int sum = 0;
        st[x][y] = true, sum += g[x][y];

        for(int i=0; i<4; ++i)
        {
                int a = x, b = y;
                while(1)
                {
                        a += dx[i], b += dy[i];
                        if(jud(a, b)) break;
                        sum += g[a][b];
                        st[a][b] = true;
                }
        }
        return sum;
}

signed main()
{
        int t; cin>>t;
        while(t--)
        {
                cin>>n>>m;
                for(int i=1; i<=n; ++i)
                {
                        for(int j=1; j<=m; ++j)
                        {
                                cin>>g[i][j];
                        }
                }
                int ans = -1;
                for(int i=1; i<=n; ++i)
                {
                        for(int j=1; j<=m; ++j)
                        {
                                ans = max(ans, cal(i, j));
                        }
                }
                cout<<ans<<'\n';
        }

        return 0;
}

E Eating Queries(前缀和 + 贪心 + 二分)

点此进入题面

题意:
在这里插入图片描述

思路:
在这里插入图片描述

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>

using namespace std;

#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 1.5e5 + 10;
int n, q, a[N], s[N];

signed main()
{
        int t; cin>>t;
        while(t--)
        {
                cin>>n>>q;
                for(int i=1; i<=n; ++i)
                {
                        scanf("%lld", &a[i]);
                }
                sort(a+1, a+n+1, greater<int>());
                for(int i=1; i<=n; ++i)
                {
                        s[i] = s[i-1] + a[i];
                }
                while(q--)
                {
                        int tgt;
                        scanf("%lld", &tgt);
                        int t = lower_bound(s+1, s+n+1, tgt) - s;
                        if(t==n+1) puts("-1");
                        else printf("%lld\n", t);
                }
        }

        return 0;
}

F Longest Strike(双指针)

点此进入题面

题意:
在这里插入图片描述
思路:
在这里插入图片描述

本题我们使用 mapmap 在哈希的时候会 按值的大小自动进行从小到大排序 即可以省去 sort

如果用 unordered_map 则应该先对 v 数组排序,

但是这样子做会喜提一发TLE
在这里插入图片描述

// two pointers
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>

using namespace std;

//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef map<int, int> mi;
typedef unordered_map<int, int> umi;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 2e5 + 10;
int a[N], n;

signed main()
{
        int t; cin>>t;
        //t = 1;

        while(t--)
        {
                int n, k; scanf("%d%d", &n, &k);
                mi hah;
                for (int i=1; i<=n; ++i)
                {
                        scanf("%d", &a[i]);
                        hah[a[i]] ++;
                }

                vi v;
                for(auto it : hah) if (it.y >= k) v.pb(it.x);

                if(!v.size()) { puts("-1"); continue; }

                int ans = -1, l = 0, r = 0;
                int i, j;
                for(i=0, j=0; i<v.size(); ++i)
                {
                        if(v[i] - v[j]==i - j) continue;
                        else
                        {
                                if(ans < v[i-1]-v[j])
                                {
                                        l = v[j], r = v[i-1];
                                        ans = v[i-1] - v[j];
                                }
                                j = i;
                        }
                }

                if(ans < v[i-1] - v[j]) l = v[j], r = v[i-1];
                cout<<l<<' '<<r<<'\n';
        }

        return 0;
}

G White-Black Balanced Subtrees(树形 dp

点此进入题面

题意:
在这里插入图片描述
在这里插入图片描述
思路:

树形 dp

状态表示:

dp[i][0]i 号节点为根节点 所代表子树的 白色节点 个数。

dp[i][1]i 号节点为根节点 所代表子树的 黑色节点 个数。

状态计算:

dp[i][0] = dp[s1][0] + dp[s2][0] + ... + dp[si][0]s1 s2 ... si 代表 节点 u 的所有子树

dp[i][1] = dp[s1][1] + dp[s2][1] + ... + dp[si][1]s1 s2 ... si 代表 节点 u 的所有子树

问题答案:

节点 u ∈ 1 ~ n 满足 dp[u][0]==dp[u][1]节点个数 count

//dp[u][0]: u th subtree's white node counts
//dp[u][1]: u th subtree's black node counts
//if(dp[u][0]==dp[u][1]) (u = 1 2 ... n) update the answer++

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>

using namespace std;

//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 4e3 + 10;
int a[N], n;
int p[N], dp[N][2];
string col;
vi g[N];

void clear()
{
        memset(dp, 0, sizeof dp);
        col.clear();
        for(int i=1; i<=n; ++i) g[i].clear();
}

void dfs(int u, int father)
{
        if(col[u]=='W') dp[u][0] = 1;
        else dp[u][1] = 1;
        for(auto v : g[u])
        {
                if(v==father) continue;
                dfs(v, u);
                dp[u][0] += dp[v][0], dp[u][1] += dp[v][1];
        }
}

signed main()
{
        int t; cin>>t;
        //t = 1;

        while(t--)
        {
                cin>>n; clear();
                for(int i=2; i<=n; ++i)
                {
                        cin>>p[i];
                        g[i].pb(p[i]), g[p[i]].pb(i);
                }
                cin>>col;
                col = " " + col;
                dfs(1, -1);
                int cnt = 0;
                for(int i=1; i<=n; ++i) if(dp[i][0]==dp[i][1]) ++cnt;
                cout<<cnt<<'\n';
        }

        return 0;
}

H1 Maximum Crossings (Easy Version)(暴力求解逆序对)

点此进入题面

题意:
在这里插入图片描述
思路:

在这里插入图片描述

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>

using namespace std;

//#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 1e3 + 10;
int a[N], n;

signed main()
{
        int t; cin>>t;
        //t = 1;

        while(t--)
        {
                cin>>n;
                for(int i=1; i<=n; ++i) cin>>a[i];
                int res = 0;
                for(int i=1; i<n; ++i)
                {
                        for(int j=i+1; j<=n; ++j)
                        {
                                if(a[i] >= a[j]) ++res;
                        }
                }
                cout<<res<<'\n';
        }

        return 0;
}

H2 Maximum Crossings (Hard Version)(树状数组求解逆序对)

点此进入题面

题意:
在这里插入图片描述
思路:

与上题一致,但是根据题目给出的 数据范围,我们要将时间复杂度控制在 O(nlogn) 以内,这里我们考虑用 树状数组 来做。

#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#include<bits/stdc++.h>

using namespace std;

#define int long long
typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef pair<ll, ll> pll;
#define pb push_back
#define pp pop_back
#define x first
#define y second
const int N = 2e5 + 10;
int a[N], n;
int tr[N];

int lowbit(int x) { return x & (-x); }

void add(int x, int v)
{
        for(; x<=n; x+=lowbit(x)) tr[x] += v;
}

int ask(int x)
{
        int res = 0;
        for (int i=x; i>0; i -= lowbit(i)) res += tr[i];
        return res;
}

void clear()
{
        memset(tr, 0, sizeof tr);
        memset(a, 0, sizeof a);
}

signed main()
{
        int t; cin>>t;
        //t = 1;

        while(t--)
        {
                cin>>n; clear();
                for(int i=1; i<=n; ++i) scanf("%lld", &a[i]);

                int res = 0;
                for(int i=n; i>=1; --i)
                {
                        res += ask(a[i]);
                        add(a[i], 1);
                }
                cout<<res<<'\n';
        }

        return 0;
}
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值