【Codeforces Round #541 (Div. 2)】 A B C D E F

A

题意 给你两个小长方形 然后他们的最左边是对准一条线的 问你旁边宽度为1范围内有多少包围的格子

我们不难发现一个长方形的贡献 是 (h+1)*2 + w 但是如果一个的w比另一个w高 我们就需要加上abs(w1-w2)的贡献即可

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;

#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))

typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;

ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;

int main()
{
    //ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    long long a,b,c,d;
    scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
    long long ans = (d+1)*2+c+(b+1)*2+a+abs(a-c);
    printf("%lld\n",ans);
    //fclose(stdin);
    //fclose(stdout);
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}


B

这题题意 是给你n个足球场上时刻的比分 问你在这一场比赛中 有多少次可能双方同分的情况

做法 我们知道只要在上一个和现在去枚举 之间两队都有一个比分范围 只要有交集就是贡献 但是要特判掉有些重复的影响

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;

#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))

typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;

ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
const int MAX_N = 10025;
struct node
{
    int l,r;
}arr[MAX_N];
int main()
{
    //ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    int n;
    long long ans = 0;
    scanf("%d",&n);
    for(int i = 1;i<=n;++i)
    {
        scanf("%d%d",&arr[i].l,&arr[i].r);
    }
    arr[0].l = 0,arr[0].r = 0;
    int st = 1;
    while(arr[st].l==0&&arr[st].r==0) ans = 1,st++;
    //dbg(ans);
    for(int i = st;i<=n;++i)
    {
        while(arr[i].l==arr[i-1].l&&arr[i].r==arr[i-1].r) i++;
        if(i>n) break;
        long long tmp = max(arr[i-1].l,arr[i-1].r);
        long long tmp_ = min(arr[i].l,arr[i].r);
        if(tmp_<tmp) continue;
        ans+= tmp_-tmp+1;
        //dbg3(i,tmp_,tmp);
        if(arr[i-1].l==arr[i-1].r&&i!=1) ans--;
        //dbg(ans);
    }
    printf("%lld\n",ans);
    //fclose(stdin);
    //fclose(stdout);
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}


C

题意 给你n个数值 让你产生一种答案序列使得相邻两个的差的最大值最小 n和1也算相邻

做法 我们按照1到中间递增 从中间到n递减的顺序插入数组即可 一次插两个 一左一右

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;

#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))

typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;

ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
const int MAX_N = 125;
int arr[MAX_N],ans[MAX_N];
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    //ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    int n;
    scanf("%d",&n);
    for(int i = 1;i<=n;++i) scanf("%d",&arr[i]);
    sort(arr+1,arr+1+n,cmp);
    if(n%2==0)
    {
        int tmp = n/2;
        ans[tmp] = arr[1],ans[tmp+1] = arr[2];
        for(int i = 1;i<=n/2;++i)
            ans[tmp-i] = arr[2*i+1],ans[tmp+1+i] = arr[2*(i+1)];
    }
    else
    {
        int tmp = n/2+1;
        ans[tmp] = arr[1];
        for(int i = 1;i<=n/2;i++)
        {
            ans[tmp-i] = arr[2*i];
            ans[tmp+i] = arr[2*i+1];
        }
    }
    for(int i = 1;i<=n;++i)
        i==n?printf("%d\n",ans[i]):printf("%d ",ans[i]);
    //fclose(stdin);
    //fclose(stdout);
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}

D

题意 给你一个n*m的矩阵 矩阵i j的意思是 ‘>’表示 第i道菜比第j道菜好吃 =是相等 那么我们知道先用并查集把等于的都处理以后 你再用拓扑写 因为等级越高的数越大 那么你应该让等级高的入度加加 这样他最后一个出现 然后队列中答案的贡献 就是 ans[x] = max(ans[pre]+1,ans[x]);

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;

#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))

typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;

ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
const int MAX_N = 1025;
char str[MAX_N][MAX_N];
bool vis[MAX_N<<1];
int indegre[MAX_N<<1],p[MAX_N<<1],eid,res,tmp,n,m,ans[MAX_N<<1],fa[MAX_N<<1];
struct edge
{
    int v,next;
}e[MAX_N*MAX_N];
void add(int u,int v)
{
    e[eid].v = v;
    e[eid].next = p[u];
    p[u] = eid++;
}
void init()
{
    memset(p,-1,sizeof(p));
    eid = 0;
}
int Find(int x)
{
    if(fa[x] == x) return x;
    return fa[x] = Find(fa[x]);
}
void Merge(int x,int y)
{
    x = Find(x), y = Find(y);
    if(x!=y)
    {
        res++;
        fa[x] = y;
    }
}
void tops()
{
    queue<int > q;
    for(int i = 1;i<=n+m;++i)
    {
        int x = Find(i);
        if(!indegre[x]&&!vis[x])
        {
            ans[x] = 1;
            q.push(x);
            tmp++;
            vis[x] = true;
        }
    }
    while(!q.empty())
    {
        int pre = q.front();
        q.pop();
        for(int i = p[pre];i+1;i=e[i].next)
        {
            int to = Find(e[i].v);
            indegre[to]--;
            ans[to] = max(ans[pre]+1,ans[to]);
            if(!indegre[to]&&!vis[to])
            {
                vis[to] = true;
                tmp++;
                q.push(to);
            }
        }
    }
}

int main()
{
    //ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    scanf("%d%d",&n,&m);
    init();
    for(int i = 1;i<=n+m;++i) fa[i] = i;
    for(int i = 1;i<=n;++i)
    {
        scanf("%s",str[i]+1);
        for(int j = 1;j<=m;++j)
        {
            if(str[i][j]=='=') Merge(i,j+n);
        }
    }
    for(int i = 1;i<=n;++i)
    {
        for(int j = 1;j<=m;++j)
        {
            if(str[i][j]=='<')
            {
                add(Find(i),Find(j+n));
                indegre[Find(j+n)]++;
            }
            else if(str[i][j]=='>')
            {
                add(Find(j+n),Find(i));
                indegre[Find(i)]++;
            }
        }
    }
    tops();
    if(n+m!=res+tmp)
    {
        printf("No\n");
        return 0;
    }
    printf("Yes\n");
    for(int i = 1;i<=n;++i)
    {
        int x = Find(i);
        i==n?printf("%d\n",ans[x]):printf("%d ",ans[x]);
    }
    for(int i = 1;i<=m;++i)
    {
        int x = Find(i+n);
        i==m?printf("%d\n",ans[x]):printf("%d ",ans[x]);
    }
    //fclose(stdin);
    //fclose(stdout);
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}


E

题意 按照一种方式生成字符串 问你最后生成的串中最长连续单个字符长度是多少

做法 我们只要枚举 a - z 贪心的去考虑整个过程 你答案最大值一定是一开始就最大值取过来去构造

所以我们以a为例 如果你输入的全是a 那么我之前最大是tmp 能插入tmp+1个地方 贡献就是 (tmp+1)*str[j].size() 

那么新tmp += (tmp+1)*str[j].size() 即可

但是万一不全是a 你可以从str[j]中取最多连续a 或者等于 1 + str[j]前面一段连续a 和str[j]后面一段连续a

枚举即可

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;

#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))

typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;

ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
const int MAX_N = 100025;
string str[MAX_N];
bool check(char ch,int i)
{
    int sz = str[i].size();
    for(int j = 0;j<sz;++j)
    {
        if(str[i][j]!=ch) return false;
    }
    return true;
}
int cal(char ch,int i)
{
    int maxx = 0,res = 0,sz = str[i].size();
    for(int j = 0;j<sz;++j)
    {
        if(str[i][j]==ch) res++;
        else maxx = max(maxx,res),res = 0;
    }
    maxx = max(maxx,res);
    return maxx;
}
int Front(char ch,int i)
{
    int res = 0,sz = str[i].size();
    for(int j = 0;j<sz;++j)
    {
        if(str[i][j]==ch) res++;
        else return res;
    }
}
int Back(char ch,int i)
{
    int res = 0,sz = str[i].size();
    for(int j = sz-1;j>=0;j--)
    {
        if(str[i][j]==ch) res++;
        else return res;
    }
}
int main()
{
    //ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    int n;
    long long ans = 0;
    scanf("%d",&n);
    for(int i = 1;i<=n;++i) cin >>str[i];
    for(int i = 0;i<26;++i)
    {
        ll tmp = 0;
        for(int j = 1;j<=n;++j)
        {
            if(tmp==0)
            {
                tmp = cal('a'+i,j);
            }
            else
            {
                int len = str[j].size();
                if(check('a'+i,j))
                {
                    tmp = tmp + (tmp+1)*len;
                }
                else
                {
                    tmp = max(1+Back('a'+i,j)+Front('a'+i,j),cal('a'+i,j));
                }
            }
        }
        ans = max(ans,tmp);
    }
    cout <<ans << endl;
    //fclose(stdin);
    //fclose(stdout);
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}


F

题意 给你几种加边方式 让你输出原先序列

我们用并查集建树 就是把两个操作合并在一起 然后从树根开始往下输出答案即可

样例的树是长这样的

#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <map>
#include <stack>
#include <set>
#include <sstream>
#include <vector>
#include <stdlib.h>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;

#define dbg(x) cout<<#x<<" = "<< (x)<< endl
#define dbg2(x1,x2) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<endl
#define dbg3(x1,x2,x3) cout<<#x1<<" = "<<x1<<" "<<#x2<<" = "<<x2<<" "<<#x3<<" = "<<x3<<endl
#define max3(a,b,c) max(a,max(b,c))
#define min3(a,b,c) min(a,min(b,c))

typedef pair<int,int> pll;
typedef long long ll;
const int inf = 0x3f3f3f3f;
const int _inf = 0xc0c0c0c0;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const ll _INF = 0xc0c0c0c0c0c0c0c0;

ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll ksm(ll a,ll b,ll mod){int ans=1;while(b){if(b&1) ans=(ans*a)%mod;a=(a*a)%mod;b>>=1;}return ans;}
ll inv2(ll a,ll mod){return ksm(a,mod-2,mod);}
//inv[1]=1;
//for(int i=2; i<M; ++i) inv[i]=1ll*(mod-mod/i)*inv[mod%i]%mod;
//for(int i=0; i<LIM; ++i) coef[i]=1ll*(P[i]-1)*inv[P[i]]%mod;
const int MAX_N = 300025;
int fa[MAX_N],n;
int p[MAX_N],eid;
void init()
{
    eid = 0;
    memset(p,-1,sizeof(p));
}
struct edge
{
    int v,next;
}e[MAX_N<<2];
void add(int u,int v)
{
    e[eid].v = v;
    e[eid].next = p[u];
    p[u] = eid++;
}
int Find(int x)
{
    if(fa[x] == x) return x;
    return fa[x] = Find(fa[x]);
}
void dfs(int x)
{
    if(x<=n) printf("%d ",x);
    for(int i = p[x];i!=-1;i=e[i].next)
    {
        int to = e[i].v;
        dfs(to);
    }
}
int main()
{
    //ios::sync_with_stdio(false);
    //freopen("a.txt","r",stdin);
    //freopen("b.txt","w",stdout);
    init();
    int a,b;
    for(int i = 1;i<=MAX_N - 2;++i) fa[i] = i;
    scanf("%d",&n);
    int cnt = n;
    for(int i = 1;i<n;++i)
    {
        scanf("%d%d",&a,&b);
        int x = Find(a),y = Find(b);
        cnt++;
        fa[x] = cnt,fa[y] = cnt;
        add(cnt,x),add(cnt,y);
    }
    dfs(cnt);
    //fclose(stdin);
    //fclose(stdout);
    //cout << "time: " << (long long)clock() * 1000 / CLOCKS_PER_SEC << " ms" << endl;
    return 0;
}


猜你喜欢

转载自blog.csdn.net/heucodesong/article/details/88660043