牛客小白月赛64 B,C,D,E

209 阅读3分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第22天,点击查看活动详情

B-小杜捕鱼_牛客小白月赛64 (nowcoder.com)

思路:对于每一个有鱼的地方都与四个顶点去算一下曼哈顿距离就可以,最后最大的就是答案

#include<bits/stdc++.h>
//#pragma-GCC-optimize("-Ofast");
#define ll long long
#define int long long
#define lowbit(x) ((x)&(-x))
#define endl '\n'
using namespace std;
const ll mod=998244353;
const ll inf=1e18;
const double pi=acos(-1);
const int N=1e6+100;
int n,m;
char ch[1005][1005];
struct node
{
    int x,y;
}a[N];
signed main()
{
  //  ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m;
    for(int i=1;i<=n;i++) cin>>(ch[i]+1);
    int cnt=0;
    a[++cnt]={1,1};
    a[++cnt]={1,m};
    a[++cnt]={n,1};
    a[++cnt]={n,m};
    int ans=0;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
    {
        if(ch[i][j]=='#')
        {
            for(int k=1;k<=cnt;k++)
            {
                ans=max(ans,abs(i-a[k].x)+abs(j-a[k].y));
               // cout<<i<<" "<<j<<" "<<a[k].x<<" "<<a[k].y<<endl;
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

C-Karashi的生日蛋糕_牛客小白月赛64 (nowcoder.com)

思路:枚举每一圈,将i/k分配给每一个蛋糕,然后将i%k轮流分配给这k个蛋糕就可以

#include<bits/stdc++.h>
//#pragma-GCC-optimize("-Ofast");
#define ll long long
#define int long long
#define lowbit(x) ((x)&(-x))
#define endl '\n'
using namespace std;
const ll mod=998244353;
const ll inf=1e18;
const double pi=acos(-1);
const int N=1e6+100;
int n,k;
vector<int>v[N];
signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>k;
    int x=1;
    for(int i=1;i<=k;i++) v[i].push_back(0);
    for(int j=1;j<=n;j++)
    {
        int y=j/k,z=j%k;
        for(int i=1;i<=k;i++)
            v[i].push_back(y);
        for(int i=1;i<=z;i++)
        {
            v[x][j]++;
            x++;if(x>k) x=1;
        }
    }
    for(int i=1;i<=k;i++)
    {
        for(int j=1;j<=n;j++) cout<<v[i][j]<<" ";
        cout<<endl;
    }
    return 0;
}

D-Karashi的树 I_牛客小白月赛64 (nowcoder.com)

思路:可以发现可以给任意点分配n个权值中的任意一个,当然权值不能重复分配;那只要出现次数最多的分配给他最大的权值,也就是谁的size越大,权值就越大,dfs求出siz,根据siz分配权值最后算出答案就可以了

#include<bits/stdc++.h>
//#pragma-GCC-optimize("-Ofast");
#define ll long long
#define int long long
#define lowbit(x) ((x)&(-x))
#define endl '\n'
using namespace std;
const ll mod=998244353;
const ll inf=1e18;
const double pi=acos(-1);
const int N=1e6+100;
int cnt,head[N];
struct Edge
{
    int from,to,next;
}e[N];
void addedge(int from,int to)
{
    e[++cnt].to=to;
    e[cnt].next=head[from];
    head[from]=cnt;
}
int n,a[N],siz[N];
void dfs(int u,int fa)
{
    siz[u]=1;
    for(int i=head[u];i;i=e[i].next)
    {
        int j=e[i].to;
        if(j==fa) continue;
        dfs(j,u);
        siz[u]+=siz[j];
    }
}
signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=2;i<=n;i++)
    {
        int x;cin>>x;
        addedge(x,i);addedge(i,x);
    }
    dfs(1,0);
    sort(siz+1,siz+n+1);
    sort(a+1,a+n+1);
    int ans=0;
    for(int i=1;i<=n;i++) ans+=siz[i]*a[i];
    cout<<ans<<endl;
    return 0;
}

E-Karashi的数组 I_牛客小白月赛64 (nowcoder.com)

思路:S(L)S(R)=S(p+1,p+len)^2+S(p+1,p+len)(a[p]+a[p+len+1])+a[p]*a[p+len+1]
S(L∪R)S(L∩R)=S(p+1,p+len)^2+S(p+1,p+len)(a[p]+a[p+len+1]),所以两者只差一个a[p]*a[p+len+1],只要至少有一个等于0两个式子就是相等的,p属于[1,n-len-1],在这个区间内去统计有多少位置是可以等零答案就是多少,注意一下分类讨论就可以,对于一个p,a[p]=0来说如果a[p-len-1]不是0,那么p就可以使得a[p-len-1]=0,答案++,如果a[p+len+1]不是0,那么p这个位置也是可以等于0的并且是新增的位置,答案++

#include<bits/stdc++.h>
//#pragma-GCC-optimize("-Ofast");
#define ll long long
#define int long long
#define lowbit(x) ((x)&(-x))
#define endl '\n'
using namespace std;
const ll mod=998244353;
const ll inf=1e18;
const double pi=acos(-1);
const int N=1e6+100;
ll qpow(ll a,ll b)
{
    ll res=1;
    while(b)
    {
        if(b&1) res=res*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return res;
}
ll getinv(ll a){return qpow(a,mod-2);}
int n,m,len,a[N];
signed main()
{
    ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
    cin>>n>>m>>len;
    int ans=0;
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        if(a[i]==0)
        {
            if(i<=n-len-1) ans++;
            if(i-len-1>=1)
            {
                if(a[i-len-1]!=0) ans++;
            }
        }
    }
    while(m--)
    {
        int pos,val;cin>>pos>>val;
        if(val>0) val=1;
        if(a[pos]==val)
        {
            cout<<ans<<endl;continue;
        }
        if(a[pos]==0&&val!=0)
        {
            if(pos+len+1<=n&&a[pos+len+1]!=0) ans--;
            if(pos-len-1>=1&&a[pos-len-1]!=0) ans--;
        }
        if(a[pos]!=0&&val==0)
        {
            if(pos+len+1<=n&&a[pos+len+1]!=0) ans++;
            if(pos-len-1>=1&&a[pos-len-1]!=0) ans++;
        }
        a[pos]=val;
        cout<<ans<<endl;
    }
    return 0;
}