• SPOJ 274 Johnny and the Watermelon Plantation(TLE)


    O(n^3)的时间复杂度,改了半天交了二三十遍,TLE到死,实在没办法了……

    跪求指点!!!

      1 #include <cstdio>
      2 #include <cstdlib>
      3 #include <cstring>
      4 #include <algorithm>
      5 
      6 using namespace std;
      7 
      8 const int MAXN = 1010;
      9 const int INF = 1 << 30;
     10 
     11 int mat[MAXN][MAXN];
     12 int SubSum[MAXN][MAXN];
     13 int tempS[MAXN];
     14 int N, K;
     15 int maxI, maxJ;
     16 int hang[MAXN], cntH;
     17 int lie[MAXN], cntL;
     18 
     19 //预处理左上角[1,1]右下角[i,j]的所有矩阵和
     20 void init()
     21 {
     22     memset( SubSum, 0, sizeof(SubSum) );
     23     for ( int i = 1; i <= maxI; ++i )
     24     {
     25         int tmps = 0;
     26         for ( int j = 1; j <= maxJ; ++j )
     27         {
     28             tmps += mat[i][j];
     29             SubSum[i][j] = SubSum[i - 1][j] + tmps;
     30         }
     31     }
     32     return;
     33 }
     34 
     35 void solved()
     36 {
     37     int ans = INF;
     38     for ( int i = 0; i < cntH; ++i ) //枚举矩形上边界
     39     for ( int j = i; j < cntH; ++j )  //枚举矩形下边界
     40     {
     41         int stL = hang[i], edL = hang[j];
     42         tempS[0] = 0;
     43         int st = 1;
     44         //扫描法,参考刘汝佳训练指南p.48 LA 2678
     45         for ( int m = 1; m <= cntL; ++m )
     46         {
     47             int k = lie[m - 1];
     48             tempS[m] = SubSum[edL][k] - SubSum[edL][k-1] - SubSum[stL-1][k] + SubSum[stL-1][k-1];
     49             tempS[m] += tempS[m - 1];
     50             if ( tempS[st - 1] > tempS[m] - K ) continue;
     51             while ( tempS[st] <= tempS[m] - K ) ++st;
     52             ans = min( ans, ( lie[m - 1] - lie[st - 1] ) * ( edL - stL ) );
     53         }
     54     }
     55     printf( "%d
    ", ans );
     56     return;
     57 }
     58 
     59 int main()
     60 {
     61     //freopen( "in.txt", "r", stdin );
     62     int T;
     63     scanf( "%d", &T );
     64     while ( T-- )
     65     {
     66         memset( mat, 0, sizeof(mat) );
     67         scanf( "%d%d", &N, &K );
     68         maxI = 0;
     69         maxJ = 0;
     70         cntL = 0, cntH = 0;
     71         bool flag = false;
     72         for ( int i = 0; i < N; ++i )
     73         {
     74             int x, y, f;
     75             scanf("%d%d%d", &x, &y, &f );
     76             hang[cntH++] = x;  //行列离散化
     77             lie[cntL++] = y;
     78             maxI = max( maxI, x );
     79             maxJ = max( maxJ, y );
     80             mat[x][y] = f;
     81             if ( f >= K )  //特殊情况,只覆盖一个点
     82             {
     83                 flag = true;
     84             }
     85         }
     86 
     87         if ( N == 1 || flag )
     88         {
     89             puts("0");
     90             continue;
     91         }
     92 
     93         sort( hang, hang + cntH );
     94         sort( lie, lie + cntL );
     95         cntH = unique( hang, hang + cntH ) - hang;
     96         cntL = unique( lie, lie + cntL ) - lie;
     97 
     98         init();
     99         solved();
    100     }
    101     return 0;
    102 }
  • 相关阅读:
    python中装饰器的原理
    python中封装、继承、多态
    Linux 中数组的使用
    Linux中环境变量中文件执行顺序
    Linux中FTP的一点理解
    原来... 拷贝构造函数的参数为什么必须使用引用类型
    C++ Programming language读书笔记
    linux 用户态 内核态
    Linux命令学习整理。
    fork &vfork --陈皓
  • 原文地址:https://www.cnblogs.com/GBRgbr/p/3223616.html
Copyright © 2020-2023  润新知