Codeforces Round #588 (Div. 2)简要题解【暴力场】

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_42671946/article/details/101449899

A - Dawid and Bags of Candies

分析:两种情况【暴力】枚举一下就可以了。

#include "bits/stdc++.h"
using namespace std;
int main(){
    int a[4];
    for (int i = 0; i < 4; ++i) {
        cin>>a[i];
    }
    sort(a,a+4);
    if(a[0]+a[3] == a[1]+a[2])puts("YES");
    else if(a[3] == a[0] + a[1] + a[2])puts("YES");
    else puts("NO");
}

B - Ania and Minimizing

分析:【暴力】模拟一下就可以了。

#include "bits/stdc++.h"

using namespace std;

int main() {
    int n, k;
    string s;
    cin >> n >> k >> s;
    if(n==1&&k==1)s="0";
    else 
    for (int i = 0; i < s.length() && k; ++i) {
        bool lim = 0;
        if (i == 0 && s[i] == '1')lim = 1;
        else if (i > 0 && s[i] == '0')lim = 1;
        if (!lim) {
            k--;
            s[i] = '0';
            if (i == 0)s[i]++;
        }
    }
    cout << s << endl;
}

C - Anadi and Domino

分析:最多有7个点,根据题意,每个点都可以视为有一个值为1-6,那么总共有6^7种情况,【暴力】枚举出每种情况然后再在图上【暴力】check一下能放几个就可以了。

#include "bits/stdc++.h"

using namespace std;
vector<int> v[10];
int n, m;
int ans;
bool vis[10];
int type[10];
map<pair<int, int>, bool> mp;

void ddfs(int u) {
    vis[u]=1;
    for (int i = 0; i < v[u].size(); ++i) {
        mp[make_pair(max(type[u], type[v[u][i]]), min(type[u], type[v[u][i]]))] = 1;
        if (vis[v[u][i]])continue;
        vis[v[u][i]] = 1;
        ddfs(v[u][i]);
    }
}

void dfs(int pos) {
    if (pos == n + 1) {
        mp.clear();
        memset(vis, 0, sizeof(vis));
        for (int i = 1; i <= n; ++i) {
            if (!vis[i])ddfs(i);
        }
        ans = max(ans, (int)mp.size());
    } else {
        for (int i = 1; i <= 6; ++i) {
            type[pos] = i;
            dfs(pos + 1);
        }
    }
}

int main() {
    ans = 0;
    cin >> n >> m;
    for (int i = 0; i < m; ++i) {
        int x, y;
        cin >> x >> y;
        v[x].push_back(y);
        v[y].push_back(x);
    }
    dfs(1);
    cout << ans << endl;
}

D - Marcin and Training Camp

分析:由题意可以知道,满足条件的一个团队,对于任意一个人都应该存在一个另外的人,这个another one的技能点可以完全覆盖这个人,那么最牛逼的那个人至少有两个,这样才能相互压制。换句话说,只要技能点相同的人数大于等于2个,就一定OK,所以我们只需要直接把这些人放进去,然后再【暴力】把这些人的技能点的子集的那种人放进去。

#include "bits/stdc++.h"

using namespace std;
long long x[7004],y[7004];
pair<long long, long long> p[7004];
unordered_map<long long, int> mp;

int main() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin>>x[i];
    }
    for (int i = 1; i <= n; ++i) {
        cin>>y[i];
    }
    for (int i = 1; i <= n; ++i) {
        p[i] = make_pair(x[i], y[i]);
        mp[x[i]]++;
    }
    long long ans = 0;
    set<int>v;
    for (auto it : mp) {
        if (it.second >= 2) {
            for (int i = 1; i <= n; ++i) {
                if ((it.first | p[i].first) == it.first){
                    v.insert(i);
                }
            }
        }
    }
    for(auto it : v){
        ans += p[it].second;
    }
    cout<<ans<<endl;
}

E - Kamil and Making a Stream

分析:直接【暴力】跑一个dfs,开个什么东西记一下这条链上的前缀gcd,然后【暴力】更新就可以了。

为什么不会T呢?显而易见,这个前缀gcd的种类数是log级别的,重复的记录一下count就可以了。

#include "bits/stdc++.h"

using namespace std;
const int mod = 1e9 + 7;
vector<int> v[100004];
long long bea[100004];
long long ans;
void dfs(int u, int pre,unordered_map<long long, int> mp) {
    for(auto it : mp){
        ans += it.first * it.second % mod;
        if(ans >=mod)ans -= mod;
    }
    for (int i = 0; i < v[u].size(); ++i) {
        if (v[u][i] == pre)continue;
        unordered_map<long long, int> temp;
        for(auto it : mp){
            long long num = __gcd(bea[v[u][i]],it.first);
            temp[num]+=it.second;
        }
        temp[bea[v[u][i]]]++;
        dfs(v[u][i],u,temp);
    }
}

int main() {
    int n;
    cin >> n;
    ans = 0;
    for (int i = 1; i <= n; ++i) {
        scanf("%lld", &bea[i]);
    }
    int x, y;
    for (int i = 0; i < n - 1; ++i) {
        scanf("%d%d", &x, &y);
        v[x].push_back(y);
        v[y].push_back(x);
    }
    unordered_map<long long, int> temp;
    temp[bea[1]]=1;
    dfs(1,-1,temp);
    cout<<ans<<endl;
}

F - Konrad and Company Evaluation

分析:老板每天点名一个人,这个人就变成工资最高的那个,点名之后好像和原来的工资没什么关系?题意坑。

显然总答案是每个点的入读*出度,我们暴力更新一个点的复杂度是关于该点的入度的,那么每次更新的平均复杂度是根号级别的,直接【暴力】更新维护答案就可以了。

#include "bits/stdc++.h"

using namespace std;
const int mod = 1e9 + 7;
long long in[100004],out[100004];
vector<int>v[100004];
int w[100004];
long long ans = 0;
void change(int u){
    ans -= in[u]*out[u];
    out[u]+=in[u];
    in[u]=0;
    for (int i = 0; i < v[u].size(); ++i) {
        ans -=in[v[u][i]]*out[v[u][i]];
        in[v[u][i]]++;
        out[v[u][i]]--;
        ans +=in[v[u][i]]*out[v[u][i]];
        v[v[u][i]].push_back(u);
    }
    v[u].clear();
}
int main() {
    int n,m;
    cin>>n>>m;
    int x,y;
    for (int i = 0; i < m; ++i) {
        scanf("%d%d",&x,&y);
        if(x>y)swap(x,y);
        in[x]++;
        out[y]++;
        v[x].push_back(y);
    }
    for (int i = 1; i <= n; ++i) {
        ans += in[i]*out[i];
    }
    cout<<ans<<endl;
    int q;
    cin>>q;
    while(q--){
        int k;
        scanf("%d",&k);
        change(k);
        cout<<ans<<endl;
    }

}

猜你喜欢

转载自blog.csdn.net/qq_42671946/article/details/101449899