Codeforces 981 共同点路径覆盖树构造 BFS/DP书架&最大值

A

/*Huyyt*/
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int dir[8][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}, {1, 1}, {1, -1}, { -1, -1}, { -1, 1}};
const int mod = 1e9 + 7;
const int gakki = 5 + 2 + 1 + 19880611 + 1e9;
const int N = 2e5 + 5;
bool ok(string x)
{
        int len = x.size();
        if (len == 1)
        {
                return true;
        }
        for (int i = 0; i < x.size() / 2; i++)
        {
                if (x[i] != x[x.size() - 1 - i])
                {
                        return false;
                }
        }
        return true;
}
int main()
{
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        string a;
        cin >> a;
        int flag = 1;
        while (flag)
        {
                if (ok(a))
                {
                        if (a.size() == 1)
                        {
                                cout << 0 << endl;
                                return 0;
                        }
                        a = a.substr(0, a.size() - 1);
                }
                else
                {
                        flag = 0;
                }
        }
        cout << a.size() << endl;
        return 0;
}
View Code

B

/*Huyyt*/
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int dir[8][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}, {1, 1}, {1, -1}, { -1, -1}, { -1, 1}};
const int mod = 1e9 + 7;
const int gakki = 5 + 2 + 1 + 19880611 + 1e9;
const int N = 2e5 + 5;
map<int,ll> mp;
int main()
{
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        ll anser=0;
        int n,m;
        cin >> n;
        int a,b;
        for(int i=1;i<=n;i++)
        {
                cin >> a >> b;
                if(mp[a]<b)
                {
                        anser+=b-mp[a];
                        mp[a]=b;
                }
        }
        cin >> m;
        for(int i=1;i<=m;i++)
        {
                cin >> a >> b;
                if(mp[a]<b)
                {
                        anser+=b-mp[a];
                        mp[a]=b;
                }
        }
        cout<<anser<<endl;
        return 0;
}
View Code

C

解:

构造题

很明显如果是有不小于一个的度大于2的点则No

如果没有度大于2的点则是一条链 直接输出两端 如果有的话则是菊花图 找每个度为1的叶子点与中心相连

/*Huyyt*/
#include<bits/stdc++.h>
#define mem(a,b) memset(a,b,sizeof(a))
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int dir[8][2] = {{0, 1}, {1, 0}, {0, -1}, { -1, 0}, {1, 1}, {1, -1}, { -1, -1}, { -1, 1}};
const int mod = 1e9 + 7;
const int gakki = 5 + 2 + 1 + 19880611 + 1e9;
const int N = 1e5 + 5;
vector<int> g[N];
int du[N];
int main()
{
        ios_base::sync_with_stdio(0);
        cin.tie(0);
        int n;
        cin >> n;
        int u, v;
        for (int i = 1; i < n; i++)
        {
                cin >> u >> v;
                g[u].pb(v), g[v].pb(u);
                du[u]++, du[v]++;
        }
        int sum = 0;
        int maxn = -1;
        int aim = 0;
        for (int i = 1; i <= n; i++)
        {
                if (du[i] > 2)
                {
                        sum++;
                }
                if (du[i] > maxn)
                {
                        aim = i;
                        maxn = du[i];
                }
        }
        if (sum > 1)
        {
                cout << "No" << endl;
                return 0;
        }
        if (maxn > 2)
        {
                cout << "Yes" << endl;
                int cnt=0;
                for(int i=1;i<=n;i++)
                {
                        if(du[i]==1)
                        {
                                cnt++;
                        }
                }
                cout << cnt << endl;
                for (int i = 1; i <= n; i++)
                {
                        if (i == aim)
                        {
                                continue;
                        }
                        if (du[i] == 1)
                        {
                                cout << aim << " " << i << endl;
                        }
                }
        }
        else
        {
                cout << "Yes" << endl;
                cout << 1 << endl;
                for (int i = 1; i <= n; i++)
                {
                        if (du[i] == 1)
                        {
                                cout << i << " ";
                        }
                }
                cout << endl;
        }
        return 0;
}
View Code

 D

题意:

给你N个书K个书架,每个书有一个价值,要求你把书分成 连续的K段 分配进这K个书架使得这几个书架的总值 AND值 最大

解:

扫描二维码关注公众号,回复: 1095253 查看本文章

贪心 DP或者BFS

首先因为是AND操作所以我们要从最高位开始贪心 如果可行的话就 ans | =1 << i

DP:

#include<bits/stdc++.h>
using namespace std;
#define LL long long
LL a[55],sum[55][55];
int n,K;
bool g[55][55];
int main(){
    cin>>n>>K;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        sum[i][i]=a[i];
        for(int j=i-1;j>=1;j--){
            sum[j][i]=sum[j+1][i]+a[j];
        }
    }
    LL ans=0;
    for(int w=60;w>=0;w--){
        memset(g,0,sizeof g);
        g[0][0]=1;
        for(int i=1;i<=n;i++){
            for(int j=i-1;j>=0;j--){
                for(int k=1;k<=K;k++){
                    if(g[j][k-1]&&(sum[j+1][i]&ans)==ans&&((sum[j+1][i]>>w)&1)){
                        g[i][k]=1;
                    }
                }
            }
        }
        if(g[n][K]){
            ans|=1LL<<w;
        }
    }
    cout<<ans<<endl;
}
View Code

BFS:

F

猜你喜欢

转载自www.cnblogs.com/Aragaki/p/9106050.html
981