Codeforces Round #541 (Div. 2) (A~F)

目录

  • Codeforces 1131

    • A.Sea Battle
    • B.Draw!
    • C.Birthday
    • D.Gourmet choice(拓扑排序)
    • E.String Multiplication(思路)
    • F.Asya And Kittens(链表)
    • G.Most Dangerous Shark

Codeforces 1131

比赛链接

hack一个暴力失败了两次最后还是没成功身败名裂= =
CF跑的也太快了吧...
不过倒也涨了不少。

A.Sea Battle

//想麻烦了,但是无所谓...
#include <set>
#include <map>
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstring>
#include <algorithm>
#define mp std::make_pair
#define pr std::pair<int,int>
#define pc putchar
#define gc() getchar()
typedef long long LL;

inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    for(;isdigit(c);now=now*10+c-48,c=gc());
    return now*f;
}
LL c(LL a,LL b)
{
    return ((a+4+b)<<1)-4;
}

int main()
{
    LL w1=read(),h1=read(),w2=read(),h2=read();
    LL ans=c(w1,h1)+c(w2,h2)-((std::min(w1,w2)+2)<<1);
    printf("%d\n",ans);

    return 0;
}

B.Draw!

//有点不知道说什么...看代码吧...
#include <set>
#include <map>
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstring>
#include <algorithm>
#define mp std::make_pair
#define pr std::pair<int,int>
#define pc putchar
#define gc() getchar()
typedef long long LL;
const int N=1e5+5;

int A[N],B[N];

inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    for(;isdigit(c);now=now*10+c-48,c=gc());
    return now*f;
}

int main()
{
    int n=read();
    for(int i=1; i<=n; ++i) A[i]=read(),B[i]=read();
    LL ans=0;
    for(int i=1,las=0; i<=n; ++i)
    {
        int x=std::max(A[i-1],B[i-1]),y=std::min(A[i],B[i]);
        x=std::max(x,las), las=y+1;
        ans+=std::max(y-x+1,0);
    }
    printf("%I64d\n",ans);

    return 0;
}

C.Birthday

sort一下从中间往左右依次分配。没证,但感觉就是对的。

//31ms  0KB
#include <set>
#include <map>
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstring>
#include <algorithm>
#define mp std::make_pair
#define pr std::pair<int,int>
#define pc putchar
#define gc() getchar()
typedef long long LL;
const int N=1e3+5;

int A[N],B[N];

inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    for(;isdigit(c);now=now*10+c-48,c=gc());
    return now*f;
}

int main()
{
    int n=read();
    for(int i=1; i<=n; ++i) A[i]=read();
    std::sort(A+1,A+1+n);
    int mid=n+1>>1; B[mid]=A[1];
    for(int i=3,t=mid-1; i<=n; i+=2) B[t--]=A[i];
    for(int i=2,t=mid+1; i<=n; i+=2) B[t++]=A[i];
    for(int i=1; i<=n; ++i) printf("%d ",B[i]);

    return 0;
}

D.Gourmet choice(拓扑排序)

容易想到拓扑一下分配数字。对于等号,就先把它们合并成一个连通块,再拓扑。
不合法情况就是同一连通块中出现了><

//61ms  43900KB
#include <set>
#include <map>
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#define mp std::make_pair
#define pr std::pair<int,int>
#define pc putchar
#define gc() getchar()
typedef long long LL;
const int N=1e6+5,M=1e3+5;

int dgr[N],bel[N],fa[N],Ans[N];
char s[M][M];
struct Graph
{
    int Enum,H[N],nxt[N],to[N];
    inline void AE(int u,int v,int f)
    {
        dgr[v]+=f, to[++Enum]=v, nxt[Enum]=H[u], H[u]=Enum;
    }
}G,T;

inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    for(;isdigit(c);now=now*10+c-48,c=gc());
    return now*f;
}
int Find(int x)
{
    return x==fa[x]?x:fa[x]=Find(fa[x]);
}
bool Check(int n,int m,int cnt)
{
    static int q[N];
    int tot=n+m,h=0,t=0;
    for(int i=1; i<=n; ++i)
        for(int j=1; j<=m; ++j)
            if(bel[i]==bel[j+n]&&s[i][j]!='=') return 0;
    for(int i=1; i<=cnt; ++i) if(!dgr[i]) q[t++]=i, Ans[i]=1;
    while(h<t)
    {
        int x=q[h++];
        for(int i=T.H[x],v; i; i=T.nxt[i])
        {
            v=T.to[i], Ans[v]=std::max(Ans[v],Ans[x]+1);
            if(!--dgr[v]) q[t++]=v;
        }
    }
    if(t<cnt) return 0;
    puts("Yes");
    for(int i=1; i<=n; ++i) printf("%d ",Ans[bel[i]]);
    puts("");
    for(int i=n+1; i<=tot; ++i) printf("%d ",Ans[bel[i]]);
    return t==cnt;
}

int main()
{
    int n=read(),m=read(),tot=n+m;
    for(int i=1; i<=tot; ++i) fa[i]=i;
    for(int i=1; i<=n; ++i)
    {
        scanf("%s",s[i]+1);
        for(int j=1; j<=m; ++j)
            if(s[i][j]=='>') G.AE(j+n,i,0);
            else if(s[i][j]=='<') G.AE(i,j+n,0);
            else fa[Find(i)]=Find(j+n);
    }
    int cnt=0;
    for(int i=1; i<=tot; ++i) if(fa[i]==i) bel[i]=++cnt;
    for(int i=1; i<=tot; ++i) if(fa[i]!=i) bel[i]=bel[Find(i)];
    for(int x=1; x<=tot; ++x)
        for(int i=G.H[x],v; i; i=G.nxt[i])
            if(bel[x]!=bel[v=G.to[i]]) T.AE(bel[x],bel[v],1);
    if(!Check(n,m,cnt)) puts("No");

    return 0;
}

E.String Multiplication(思路)

从后往前对最后一个字符串\(p_n\)的前后缀是否相同讨论一下。具体看这里吧不想写了= =
可以像上面那样递归去做,也可以从\(p_1\)往后递推。因为用到的是某个字符的最长连续子串,所以令\(f[i][j]\)表示\(p_1\cdot p_2\cdot...\cdot p_i\)中\(j\)字符的最长连续长度,转移时判一下\(p_{i+1}\)是否都是由\(j\)字符构成的,是就用\(len\times(f[i][j]+1)+f[i][j]\)更新,否则用\(1+j字符的最长前后缀\)更新(\(p_{i-1}\)中含\(j\)字符才能转移)。
复杂度\(O(\sum|p_i|)\)(递归)或\(O(26\sum|p_i|)\)(递推)(然而前者常数比较大)。

//46ms  10100KB
#include <cstdio>
#include <cstring>
#include <algorithm>
#define S 26
typedef long long LL;
const int N=1e5+5;

int f[N][S],pre[S],suf[S];
char s[N];

void Solve(int *f)
{
    scanf("%s",s+1);
    int l=strlen(s+1);
    for(int j=0; j<S; ++j)
    {
        int mx=0;
        for(int i=1,cnt=0; i<=l; ++i)
            if(s[i]==j+'a') mx=std::max(mx,++cnt);
            else cnt=0;
        f[j]=mx, pre[j]=suf[j]=0;
        for(int i=1; i<=l; ++i)
            if(s[i]==j+'a') ++pre[j];
            else break;
        for(int i=l; i; --i)
            if(s[i]==j+'a') ++suf[j];
            else break;
    }
}

int main()
{
    int n; scanf("%d",&n);
    Solve(f[1]);
    for(int i=2; i<=n; ++i)
    {
        Solve(f[i]);
        int l=strlen(s+1);
        for(int j=0; j<S; ++j)
            if(f[i-1][j])
                if(pre[j]!=l) f[i][j]=std::max(f[i][j],pre[j]+suf[j]+1);
                else f[i][j]=std::max(f[i][j],l*(f[i-1][j]+1)+f[i-1][j]);
    }
    int ans=0;
    for(int i=0; i<S; ++i) ans=std::max(ans,f[n][i]);
    printf("%d\n",ans);

    return 0;
}

F.Asya And Kittens(链表)

容易发现只要模拟一下按顺序合并连通块即可。可以用vector+启发式合并,也可以链表。用链表复杂度\(O(n\alpha(n))\)。

//78ms  1600KB
#include <set>
#include <map>
#include <cstdio>
#include <cctype>
#include <vector>
#include <cstring>
#include <algorithm>
#define mp std::make_pair
#define pr std::pair<int,int>
#define pc putchar
#define gc() getchar()
typedef long long LL;
const int N=150005;

int fa[N],R[N],ed[N];

inline int read()
{
    int now=0,f=1;register char c=gc();
    for(;!isdigit(c);c=='-'&&(f=-1),c=gc());
    for(;isdigit(c);now=now*10+c-48,c=gc());
    return now*f;
}
int Find(int x)
{
    return x==fa[x]?x:fa[x]=Find(fa[x]);
}

int main()
{
    int n=read();
    for(int i=1; i<=n; ++i) fa[i]=ed[i]=i;
    for(int i=1; i<n; ++i)
    {
        int x=read(),y=read();
        int r1=Find(x),r2=Find(y);
        fa[r2]=r1, R[ed[r1]]=r2, ed[r1]=ed[r2];
    }
    for(int i=1; i<=n; ++i)
        if(fa[i]==i)
        {
            for(int x=i; x; x=R[x]) printf("%d ",x);
            break;
        }

    return 0;
}

G.Most Dangerous Shark

待填坑(怕是永远也填不上了)

原文地址:https://www.cnblogs.com/SovietPower/p/10425364.html

时间: 2024-10-11 07:41:17

Codeforces Round #541 (Div. 2) (A~F)的相关文章

Codeforces Round #541 (Div. 2) 题解

Codeforces Round #541 (Div. 2) 题目链接:https://codeforces.com/contest/1131 A. Sea Battle 题意: 给出两个矩形的宽和高,满足第一个矩形的左上顶点为(0,0),右下顶点为(w1,-h1):第二个矩形的坐下顶点为(0,0),右上顶点为(w2,h2).然后求围绕这两个矩形一圈的格子个数为多少. 题解: 利用二维前缀和的思路推导一下公式就行了,公式也有很多吧==我当时就是大概模拟了一下.. 代码如下: #include <

Codeforces Round #496 (Div. 3)A~F

(寒假训练赛,也是lj难得补完的一场 https://codeforces.com/contest/1005 A.题意是  每一个楼梯有x个台阶,小女孩爬楼的时候会从1开始数每层楼有几个台阶,现在给给出n个数字a1~an,代表着小女孩爬楼时数数的序列,求有多少层楼梯,并且输出每层楼梯台阶数. 解法:for循环模拟小女孩从1开始数,数到下一个1的话楼层++,然后把他前一个数存进去. int now = 0; for(int i = 0;i < n;++i){ cin>>a; if(a ==

Codeforces Round #516 (Div. 2) (A~F)

目录 A.Make a triangle! B.Equations of Mathematical Magic C.Oh Those Palindromes D.Labyrinth(BFS) E.Dwarves,Hats and Extrasensory Abilities(交互 二分) D.Labyrinth E.Dwarves,Hats and Extrasensory Abilities 比赛链接 A.Make a triangle! 不放了. B.Equations of Mathema

codeforces Round #541 (Div 2)

A Sea Battle 平移过后即外围的$(w_{2} + 2) \times  (h_{1} + h_{2} + 2)$的矩形周长; 1 #include<bits/stdc++.h> 2 using namespace std; 3 int main(){ 4 int w1,w2,h1,h2; 5 cin>>w1>>h1>>w2>>h2; 6 int a=w1+2,b=h1+h2+2; 7 cout<<((a+b)<<

Codeforces Round #541 (Div. 2) E 字符串 + 思维 + 猜性质

https://codeforces.com/contest/1131/problem/D 题意 给你n个字符串,字符串长度总和加起来不会超过1e5,定义字符串相乘为\(s*s1=s1+s[0]+s1+s[1]+s1+...+s1+s[size-1]+s1+s[size]+s1\),求n个字符串依次相乘后最长连续字符相同的子序列长度 题解 鬼畜的题意 or 难以优化的复杂度,都需要观察性质才能做,第二串要插入第一个串每个字符之间,可以看出字符数增长的速度很快,所以并不能把整个字符存下来 只看一种

Codeforces Round #541 (Div. 2) D 并查集 + 拓扑排序

https://codeforces.com/contest/1131/problem/D 题意 给你一个n*m二维偏序表,代表x[i]和y[j]的大小关系,根据表构造大小分别为n,m的x[],y[],使得两个数组中最大的数尽量小 题解 按照偏序表,构造出从小到大的拓扑图 如何解决相等的数的偏序关系? 用并查集缩点后再进行拓扑排序 如何解决最大的数最小? 只需要使得同一层的数相同就行,可以一批处理栈中的元素,对于一批栈中的元素产生的新点,先放进一个容器里,然后等到这批栈清空了,再把这个容器中的点

Codeforces Round #486 (Div. 3) F. Rain and Umbrellas

Codeforces Round #486 (Div. 3) F. Rain and Umbrellas 题目连接: http://codeforces.com/group/T0ITBvoeEx/contest/988/problem/E Description Polycarp lives on a coordinate line at the point x=0. He goes to his friend that lives at the point x=a. Polycarp can

Codeforces Round #501 (Div. 3) F. Bracket Substring

题目链接 Codeforces Round #501 (Div. 3) F. Bracket Substring 题解 官方题解 http://codeforces.com/blog/entry/60949 ....看不懂 设dp[i][j][l]表示前i位,左括号-右括号=j,匹配到l了 状态转移,枚举下一个要填的括号,用next数组求状态的l,分别转移 代码 #include<bits/stdc++.h> using namespace std; const int maxn = 207;

[Codeforces Round #617 (Div. 3)] 题解 A,B,C,D,E1,E2,F

[Codeforces Round #617 (Div. 3)] 题解 A,B,C,D,E1,E2,F 1296A - Array with Odd Sum 思路: 如果一开始数组的sum和是奇数,那么直接YES, 否则:如果存在一个奇数和一个偶数,答案为YES,否则为NO 代码: int n; int a[maxn]; int main() { //freopen("D:\\code\\text\\input.txt","r",stdin); //freopen(