解题思路:
明显答案有单调性,故可以使用二分,将灰尘度看为路径长度,可以使用最短路求解。
注意事项:
注意一些限制条件,复杂度(O(n^3logm))。
参考代码:


#include

using namespace std;

#define maxx 101000

#define int long long

#define INF 0x3f3f3f3f

int n,Q,l=0,r=0;

int G[102][102];

int all[102][102];

int lim[102][102];

int check(int i)

{

  int now=(i-1)%n;

  int sum=(i-1)/n;

  for(int i=0;i<n;++i)

   for(int j=0;j<n;++j)

    all[i][j]=G[i][j];

  for(int i=0;i<n;++i)

   for(int j=0;j<n;++j)

    {if(i<=now) --all[i][j];

    if(j<=now) --all[i][j];

    all[i][j]=all[i][j]-2*sum;

    all[i][j]=max(all[i][j],lim[i][j]);

    }

   for(int k=0;k<n;++k)

    for(int i=0;i<n;++i)

     for(int j=0;j<n;++j)

      all[i][j]=min(all[i][j],all[i][k]+all[k][j]);

       int ans=0;

   for(int i=0;i<n;++i)

     for(int j=0;j<n;++j)

      ans+=all[i][j];

      if(ans<=Q) return 1;

      else return 0;

}


signed main()

{

  cin>>n>>Q;

 

  for(int i=0;i<n;++i)

    for(int j=0;j<n;++j)

      cin>>G[i][j];

 for(int i=0;i<n;++i)

    for(int j=0;j<n;++j)

      cin>>lim[i][j];

  for(int i=0;i<n;++i)

    for(int j=0;j<n;++j)

     r=max(r,G[i][j]-lim[i][j]);

     r=r*n;

     if(!check(r)) {cout<<"-1"; return 0;}

     if(check(l)) {cout<<"0";return 0;}

   while(l<r)

    {

      int mid=(l+r)/2;

      if(!check(mid)) l=mid+1;

      else r=mid;

    }

    cout<<l;

 


}


 

0.0分

1 人评分

新上线《蓝桥杯辅导》课程,近五年的蓝桥杯省赛与国赛真题都有,从读题开始理解题意、梳理思路、实现代码再提交评测全过程,可有效提升获奖比例甚至进国赛!课程介绍、试听请猛击这里

  评论区

  • «
  • »