Biathlon Track

Codeforces Round #242 (Div. 2) D:http://codeforces.com/contest/424/problem/D

题意:给你一个n*m的矩阵,每个格子上面有个数字,在相邻格子之间会有一定的费用,费用根据相邻格子的大小关系确定。让你费用最接近一个数的矩阵。

题解:一看题目,想了一下,预处理,然后猜到要用二分。但是二维的怎么二分,一直没有想到什么办法,一直想的是(n*mlog(n*m))的算法,所以不对了。其实应该固定一个起点,作为矩阵的左上角的点,然后枚举右下角的纵坐标,对于右下角的横坐标就可以二分寻找了。但是这里是找最接近的数,一开始以为二分找不到,现在才知道二分的最后可以找到的就是最接近的那个数,同时二分的写法也要注意,不能写成a[mid]<=number,这样会陷入死循环。还有,这一题要预处理出一些点的距离。其实,这一题还可以直接打暴力,四层for也是能过的。

  1 #include<iostream>
  2 #include<cstring>
  3 #include<cstdio>
  4 #include<algorithm>
  5 using namespace std;
  6 const int N=306;
  7 int a[N][N];
  8 int l[N][N],r[N][N],u[N][N],d[N][N];
  9 int n,m,t;
 10 int tp,tu,td;
 11 void solve(){
 12    memset(l,0,sizeof(l));
 13    memset(r,0,sizeof(r));
 14    memset(u,0,sizeof(u));
 15    memset(d,0,sizeof(d));
 16    for(int i=1;i<=n;i++){
 17     for(int j=1;j<=m;j++){
 18         l[i][j]=l[i][j-1];
 19         if(j==1)continue;
 20         if(a[i][j]>a[i][j-1])
 21             l[i][j]+=tu;
 22         else if(a[i][j]==a[i][j-1])
 23             l[i][j]+=tp;
 24         else
 25             l[i][j]+=td;
 26      }
 27    }
 28    for(int i=1;i<=n;i++){
 29     for(int j=m;j>=1;j--){
 30         r[i][j]=r[i][j+1];
 31         if(j==m)continue;
 32         if(a[i][j]>a[i][j+1])
 33             r[i][j]+=tu;
 34         else if(a[i][j]==a[i][j+1])
 35             r[i][j]+=tp;
 36         else
 37             r[i][j]+=td;
 38      }
 39    }
 40    for(int j=1;j<=m;j++){
 41     for(int i=1;i<=n;i++){
 42         u[i][j]=u[i-1][j];
 43         if(i==1)continue;
 44         if(a[i][j]>a[i-1][j])
 45           u[i][j]+=tu;
 46         else if(a[i][j]==a[i-1][j])
 47             u[i][j]+=tp;
 48         else
 49             u[i][j]+=td;
 50     }
 51    }
 52    for(int j=1;j<=m;j++){
 53     for(int i=n;i>=1;i--){
 54         d[i][j]=d[i+1][j];
 55         if(i==n)continue;
 56         if(a[i][j]>a[i+1][j])
 57           d[i][j]+=tu;
 58         else if(a[i][j]==a[i+1][j])
 59             d[i][j]+=tp;
 60         else
 61             d[i][j]+=td;
 62     }
 63    }
 64 }
 65 int getsum(int l1,int r1,int l2,int r2){
 66     return l[l1][r2]-l[l1][r1]+u[l2][r2]-u[l1][r2]+r[l2][r1]-r[l2][r2]+d[l1][r1]-d[l2][r1];
 67 }
 68 int ans,x1,x2,y1,y2;
 69 int main(){
 70   scanf("%d%d%d",&n,&m,&t);
 71   scanf("%d%d%d",&tp,&tu,&td);
 72   for(int i=1;i<=n;i++)
 73     for(int j=1;j<=m;j++)
 74      cin>>a[i][j];
 75       solve();
 76       ans=2e9;
 77     for(int i=1;i<=n;i++){
 78         for(int j=1;j<=m;j++){
 79             for(int  k=j+2;k<=m;k++){
 80                int l=i+2,r=n;
 81                if(l>r)continue;
 82                while(l<r){
 83                 int mid=(l+r)/2;
 84                 int temp=getsum(i,j,mid,k);
 85                 if(temp>=t){
 86                     r=mid;
 87                 }
 88                 else
 89                     l=mid+1;
 90                }
 91               int ts=getsum(i,j,l,k);
 92               if(abs(ts-t)<abs(ans-t)){
 93                  ans=ts;
 94                  x1=i;y1=j;
 95                  x2=l;y2=k;
 96               }
 97               if(l<n){
 98                 ts=getsum(i,j,l+1,k);
 99               if(abs(ts-t)<abs(ans-t)){
100                  ans=ts;
101                  x1=i;y1=j;
102                  x2=l+1;y2=k;
103               }
104             }
105               if(l>i+2){
106                 ts=getsum(i,j,l-1,k);
107               if(abs(ts-t)<abs(ans-t)){
108                  ans=ts;
109                  x1=i;y1=j;
110                  x2=l-1;y2=k;
111               }
112             }
113         }
114     }
115   }
116   printf("%d %d %d %d\n",x1,y1,x2,y2);
117 
118 }
View Code

 

转载于:https://www.cnblogs.com/chujian123/p/3884803.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值