LOADING

加载过慢请开启缓存,浏览器默认开启

CF_802

802 div 2的6道题,这场比较简单

A
显然先从原点走到第一行的最后一个点然后向下走最方便,我们直接计算即可

void solve()
{
  ll n,m;
  cin>>n>>m;
  ll one=(1+m)*m/2;
  ll two=(n-1)*m;
  ll three=(n-1)*n*m/2;
  cout<<one+two+three<<'\n';
  return;
}



B

由于我们需要创造出回文数,那么如果第一位为9,我们创建多一位的回文数也就是全为1,否则我们创建全为9的回文数

void solve()
{
  int n;cin>>n;
  vector<int>a(n);
  for(int i=0;i<n;++i)
  {
    char c;
    cin>>c;
    a[i]=c-'0';
  }
  vector<int>ans;
  if(a[0]==9)
  {
    ans.assign(n+1,1);
    for(int i=n;i>0;--i)
    {
        if(ans[i]>=a[i-1])
        {
            ans[i]-=a[i-1];
        }
        else
        {
           int k=i-1;
           while(ans[k]==0)
           {
                ans[k]=9;
                --k;
           }
           ans[k]--;
           (ans[i]-=a[i-1])+=10;
        }
    }
  }
  else
  {
    ans.assign(n,9);
    for(int i=n-1;i>=0;--i)
    {
        if(ans[i]>=a[i])
        {
            ans[i]-=a[i];
        }
        else
        {
           int k=i-1;
           while(ans[k]==0)
           {
                ans[k]=9;
                --k;
           }
           ans[k]--;
           (ans[i]-=a[i])+=10;
        }
    }
  }
  int st=0;
  while(ans[st]==0)st++;
  for(int i=st;i<ans.size();++i)
  {
    cout<<ans[i];
  }
  cout<<'\n';
  return;
}

C

针对范围的相同类型修改,我们一般直接考虑差分,这里也是一样,我们直接把对应的几种操作方式进行对照

1.a[1->i]-=1 -> b[1]+=1 b[i+1]+=1

2.a[i->n]-=1 -> b[i]-=1

3.a[1->n]+=1 -> b[1]+=1

最后别忘了处理b[1],注意开longlong,我这里#define int ll了已经

void solve()
{
  int n;cin>>n;
  vector<int>a(n+1),b(n+1);
  for(int i=1;i<=n;++i)cin>>a[i];
  for(int i=1;i<=n;++i)b[i]=a[i]-a[i-1];
  int ans=0;
  for(int i=2;i<=n;++i)
  {
    if(b[i]>0)
    {
        ans+=b[i];
    }
    else
    {
        ans+=abs(b[i]);
        b[1]-=abs(b[i]);
    }
  }
  ans+=abs(b[1]);
  cout<<ans<<'\n';
  return;
}

D
贪心题,首先我们考虑什么样的情况无解,那就是前i个容器的体积的和要大于i个水龙头打开的放水量,所以我们取最大的平均值,如果大于那么就无解

之后的水龙头数量很简单,就是体积和除以时间即可

void solve()
{
  ll n;cin>>n;
  vector<ll>a(n+1);
  ll sum=0;
  db average=0;
  for(int i=1;i<=n;++i)
  {
    cin>>a[i];
    sum+=a[i];
    average=max(average,(double)sum*1.0/i);
  }
  int q;
  cin>>q;
  while(q--)
  {
    ll t;cin>>t;
    if(t<average)
    {
        cout<<-1<<'\n';
    }
    else
    {
        cout<<(sum-1)/t+1<<'\n';
    }
  }
  return;
}

E

首先我们考虑什么时候输出2,对于每一个需要交换的点来说,他身边最多有4个点无效,所以对于一次交换来说,我们最多改变5个点的正确性

之后我们模拟点对的交换即可,需要注意这种情况不要反复枚举,如果两个点对在一个6x6的块中

vector<vector<int>>dir={{0,0},{-1,0},{1,0},{0,-1},{0,1}};
void solve()
{
  int n,m;
  cin>>n>>m;
  vector mp(n+1,vector<int>(m+1)),vis(mp),have(mp);
  for(int i=1;i<=n;++i)
  {
    for(int j=1;j<=m;++j)
    {
        cin>>mp[i][j];
    }
  }
  int in_cnt=0,sx=-1,sy=-1,ans=0;
  auto check=[&](int i,int j)
  {
    return i>=1&&i<=n&&j>=1&&j<=m;
  };
  for(int i=1;i<=n;++i)
  {
    for(int j=1;j<=m;++j)
    {
        if(mp[i][j]==1)continue;
        int cnt=0;
        for(int k=1;k<5;++k)
        {
            int ni=i+dir[k][0];
            int nj=j+dir[k][1];
            if(!check(ni,nj))continue;
            cnt+=mp[ni][nj]<mp[i][j];
        }
        if(cnt==0)
        {
            ++in_cnt;
            sx=i,sy=j;
            have[i][j]=1;
        }
    }
  }
  if(in_cnt==0)
  {
    cout<<0<<'\n';
    return;
  }
  if(in_cnt>10)
  {
    cout<<2<<'\n';
    return;
  }
  auto cal=[&](int x,int y)
  {
    if(mp[x][y]==1)return 0;
    bool f=false;
    for(int i=1;i<5;++i)
    {
        int nx=x+dir[i][0];
        int ny=y+dir[i][1];
        if(check(nx,ny)&&mp[nx][ny]<mp[x][y])
        {
            f=true;
            break;
        }
    }
    if(f&&have[x][y])return 1;
    if(!f&&!have[x][y])return -1;//because we deal with a wrong point need to balace 1
    return 0;
  };
  auto try_one=[&](int x,int y)
  {
    for(int i=1;i<=n;++i)
    {
        for(int j=1;j<=m;++j)
        {
            if(vis[i][j])continue;
            int now_cnt=0;
            swap(mp[i][j],mp[x][y]);
            for(int k=0;k<5;++k)
            {
                int ni=i+dir[k][0],nj=j+dir[k][1];
                if(check(ni,nj))now_cnt+=cal(ni,nj);
            }
            for(int k=0;k<5;++k)
            {
                int nx=x+dir[k][0],ny=y+dir[k][1];
                if(check(nx,ny)&&abs(nx-i)+abs(ny-j)>1)now_cnt+=cal(nx,ny);
            }
            if(now_cnt==in_cnt)++ans;
            swap(mp[i][j],mp[x][y]);
        }
    }
  };
  for(int i=0;i<5;++i)
  {
    int nx=sx+dir[i][0],ny=sy+dir[i][1];
    if(check(nx,ny))
    {
        vis[nx][ny]=1;
        try_one(nx,ny);
    }
  }
  if(ans)
  {
    cout<<1<<' '<<ans<<'\n';
  }
  else
  {
    cout<<2<<'\n';
  }
  return;
}

F

还没做,贴一个别的大佬的做法(明天一定补上)

(https://www.cnblogs.com/zjsqwq/p/16442980.html)