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 ",x1,y1,x2,y2); 117 118 }