Codeforces Round #662 (Div. 2) / contest 1393

目录

        • A Rainbow Dash, Fluttershy and Chess Coloring
        • B Applejack and Storages
        • C Pinkie Pie Eats Patty-cakes
        • D Rarity and New Dress
        • E1
        • E2


A B C D E1 E2

( √:做出; ●:尝试未做出; ○:已补题 )


题目地址:https://codeforces.com/contest/1393



A Rainbow Dash, Fluttershy and Chess Coloring

题意:签到题

思路

代码

#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include 
#include 
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
    int x=0,flag=1; char c=getchar();
    while((c>'9' || c<'0') && c!='-') c=getchar();
    if(c=='-') flag=0,c=getchar();
    while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return flag?x:-x;
}

int main()
{
    int t=read();
    while(t--)
    {
        int n=read();
        cout<<n/2+1<<endl;
    }

    return 0;
}



B Applejack and Storages

题意:要求维护若干条边,每次可以增加一条某个长度的边,或者删除一条某个长度的边,你需要在每次操作结束后回答,这些边是否可以组成一个正方形加一个长方形。

思路:动态维护两个数 n2 和 n4(分别表示可以组成两条相同的边的对数,以及可以组成四条相同的边的对数),因为只需要一个正方形一个长方形,所以只需要在 8 以内更改这两个数就行了。最后存在的条件是 n4>=2 || (n4>0 && n2>=2)

代码

#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include 
#include 
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
    int x=0,flag=1; char c=getchar();
    while((c>'9' || c<'0') && c!='-') c=getchar();
    if(c=='-') flag=0,c=getchar();
    while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return flag?x:-x;
}

const int maxn=1e5+5;
int a[maxn],n2=0,n4=0;
char s[10];

void add(int x)
{
    a[x]++;
    if(a[x]==2) n2++;
    else if(a[x]==4) n2--,n4++;
    else if(a[x]==6) n2++;
    else if(a[x]==8) n2--,n4++;
}

void del(int x)
{
    a[x]--;
    if(a[x]==1) n2--;
    else if(a[x]==3) n2++,n4--;
    else if(a[x]==5) n2--;
    else if(a[x]==7) n2++,n4--;
}

int main()
{
    int n=read();
    REP(i,1,n)
    {
        int x=read();
        add(x);
    }
    int q=read();
    while(q--)
    {
        scanf("%s",s);
        int x=read();
        if(s[0]=='+') add(x);
        else if(s[0]=='-') del(x);
        puts((n4>=2 || (n4==1 && n2>=2))?"YES":"NO");
    }

    return 0;
}



C Pinkie Pie Eats Patty-cakes

题意:有很多饼干,要把他们排成一排,把两两相同的饼干之间的间距拿出来,取这所有间距之间的最小值,目标是要使这个最小值最大,问这个最小值最大是多少。

思路:一开始一直在想二分,后来想着想着发现,我们只需要考虑最多的饼干就行了,因为少的那些完全可以在充分满足 最多的饼干之后,以同样的间距插进去,因为它们不需要最多的那么多位置,所以一定可行。还需要考虑最多的饼干有多少种,然后把它们平均分进去,算一下间距就行了。

算间距的方法大概就是,假设有 tot 种最多的饼干,最多的饼干每种有 m 个,那么其中的一个的第一个就放在第一个位置,最后一个应该放在第 n-tot+1 个位置,然后中间平均放,然后计算间距即可。

代码

#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include 
#include 
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
    int x=0,flag=1; char c=getchar();
    while((c>'9' || c<'0') && c!='-') c=getchar();
    if(c=='-') flag=0,c=getchar();
    while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return flag?x:-x;
}

const int maxn=1e5+5;
int num[maxn];

int main()
{
    int T=read();
    while(T--)
    {
        int n=read();
        REP(i,1,n) num[i]=0;
        REP(i,1,n)
        {
            int x=read();
            num[x]++;
        }
        int m=0;
        REP(i,1,n) m=max(m,num[i]);
        int tot=0;
        REP(i,1,n) tot+=num[i]==m;
        printf("%d\n",(n-m-tot+1)/(m-1));
    }

    return 0;
}



D Rarity and New Dress

题意:给你一块布,布上面每个方块有一个颜色,你要从布上面剪下一个呈 45° 的正方形,并且要求这个正方形的颜色只有一种,问有多少种剪法。以下这三种都是合法的 45° 的正方形:

Codeforces Round #662 (Div. 2) / contest 1393_第1张图片

(图片截图于 https://codeforces.com/contest/1393/problem/D)

思路:设 f(i, j) 表示以 (i, j) 作为底端的点,往上能延伸的正方形的最大边长,那么对于每个 f(i, j) ,假设它和它 上面、左上、右上、上上 之间有不一样的颜色,那么 f(i, j)=1;如果全都一样,那么就取上面四个的 f 中的最小值 minx,那么 f(i, j)=minx+1 。最后计算 f 的和就是答案。

代码

#define DIN freopen("input.txt","r",stdin);
#define DOUT freopen("output.txt","w",stdout);
#include 
#include 
#define mem(a,b) memset(a,b,sizeof(a))
#define REP(i,a,b) for(int i=(a);i<=(int)(b);i++)
#define REP_(i,a,b) for(int i=(a);i>=(b);i--)
#define pb push_back
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> P;
int read()
{
    int x=0,flag=1; char c=getchar();
    while((c>'9' || c<'0') && c!='-') c=getchar();
    if(c=='-') flag=0,c=getchar();
    while(c<='9' && c>='0') {x=(x<<3)+(x<<1)+c-'0';c=getchar();}
    return flag?x:-x;
}

const int maxn=2005;
int f[maxn][maxn];
char s[maxn][maxn];

int main()
{
    int n=read(),m=read();
    REP(i,1,n) scanf("%s",s[i]+1);
    REP(i,1,2) REP(j,1,m) f[i][j]=1;
    REP(i,3,n) REP(j,1,m)
    {
        if(j==1 || j==m) {f[i][j]=1; continue;}
        if(s[i][j]!=s[i-1][j-1] || s[i][j]!=s[i-1][j] ||s[i][j]!=s[i-1][j+1] || s[i][j]!=s[i-2][j])
        {
            f[i][j]=1;
            continue;
        }
        int x=100000;
        x=min(x,f[i-1][j-1]);
        x=min(x,f[i-1][j]);
        x=min(x,f[i-1][j+1]);
        x=min(x,f[i-2][j]);
        f[i][j]=x+1;
    }
    LL ans=0;
    REP(i,1,n) REP(j,1,m) ans+=f[i][j];
    cout<<ans;

    return 0;
}



E1

题意

思路

代码




E2

题意

思路

代码


你可能感兴趣的:(codeforces)