标签:
题意大致是这样的:有一个有n行、每行m个格子的矩形,每次往指定格子里填石子,如果指定格子里已经填过了,则找到与其曼哈顿距离最小的格子,然后填进去,有多个的时候依次按x、y从小到大排序然后取最小的。输出每次填的格子的坐标。
思路:这道题出自Codeforces Round #126 (Div. 2)是个暴力优化的题。如果指定格子未填,则填到里面。否则枚举曼哈顿距离,然后枚举格子找答案。裸的暴力太慢了,主要是因为每次曼哈顿距离都是从1开始搜索,如果每次指定的坐标都是同一个,则做了大量的重复工作。不妨用一个数组r[x][y]表示与(x,y)这个格子曼哈顿距离不超过r[x][y]的格子全部被填过了。r数组满足这样一个关系,r[x][y]>=r[x‘][y‘]-dist{(x,y),(x‘,y‘)},每次使用r[x][y]之前,用(x,y)周围的一些点更新下就行了。复杂度比较模糊,必须承认,这种优化简直太神,对于极端数据和随机数据都灰常之快
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | /* ******************************************************************************** */ #include <iostream> // #include <cstdio> // #include <cmath> // #include <cstdlib> // #include <cstring> // #include <vector> // #include <ctime> // #include <deque> // #include <queue> // #include <algorithm> // #include <map> // #include <cmath> // using namespace std; // // #define pb push_back // #define mp make_pair // #define X first // #define Y second // #define all(a) (a).begin(), (a).end() // #define fillchar(a, x) memset(a, x, sizeof(a)) // // typedef pair< int , int > pii; // typedef long long ll; // typedef unsigned long long ull; // // #ifndef ONLINE_JUDGE // void RI(vector< int >&a, int n){a.resize(n); for ( int i=0;i<n;i++) scanf ( "%d" ,&a[i]);} // void RI(){} void RI( int &X){ scanf ( "%d" ,&X);} template < typename ...R> // void RI( int &f,R&...r){RI(f);RI(r...);} void RI( int *p, int *q){ int d=p<q?1:-1; // while (p!=q){ scanf ( "%d" ,p);p+=d;}} void print(){cout<<endl;} template < typename T> // void print( const T t){cout<<t<<endl;} template < typename F, typename ...R> // void print( const F f, const R...r){cout<<f<< ", " ;print(r...);} template < typename T> // void print(T*p, T*q){ int d=p<q?1:-1; while (p!=q){cout<<*p<< ", " ;p+=d;}cout<<endl;} // #endif // ONLINE_JUDGE // template < typename T> bool umax(T&a, const T&b){ return b<=a? false :(a=b, true );} // template < typename T> bool umin(T&a, const T&b){ return b>=a? false :(a=b, true );} // template < typename T> // void V2A(T a[], const vector<T>&b){ for ( int i=0;i<b.size();i++)a[i]=b[i];} // template < typename T> // void A2V(vector<T>&a, const T b[]){ for ( int i=0;i<a.size();i++)a[i]=b[i];} // // const double PI = acos (-1.0); // const int INF = 1e9 + 7; // // /* -------------------------------------------------------------------------------- */ const int maxn = 2e3 + 7; bool plot[maxn][maxn]; int r[maxn][maxn]; int n, m, k; int check( int row, int col) { if (col >= 0 && col < m) return true ; return false ; } int main() { #ifndef ONLINE_JUDGE freopen ( "in.txt" , "r" , stdin); //freopen("out.txt", "w", stdout); #endif // ONLINE_JUDGE cin >> n >> m >> k; for ( int i = 0; i < k; i ++) { int x, y; scanf ( "%d%d" , &x, &y); x --; y --; if (!plot[x][y]) { printf ( "%d %d\n" , x + 1, y + 1); plot[x][y] = true ; continue ; } for ( int d = 1; d <= 3; d ++) { int Max = min(n, x + d + 1); for ( int row = max(0, x - d); row < Max; row ++) { int t = d - abs (x - row), col1 = y - t, col2 = y + t; if (check(row, col1)) umax(r[x][y], r[row][col1] - d); if (check(row, col2)) umax(r[x][y], r[row][col2] - d); } } for ( int d = r[x][y] + 1; ; d ++) { int Max = min(n, x + d + 1); bool ok = false ; for ( int row = max(0, x - d); row < Max; row ++) { int t = d - abs (x - row), col1 = y - t, col2 = y + t; if (check(row, col1) && !plot[row][col1]) { ok = true ; printf ( "%d %d\n" , row + 1, col1 + 1); plot[row][col1] = true ; break ; } if (check(row, col2) && !plot[row][col2]) { ok = true ; printf ( "%d %d\n" , row + 1, col2 + 1); plot[row][col2] = true ; break ; } } if (ok) { r[x][y] = d - 1; break ; } } } return 0; } /* ******************************************************************************** */ |
[codeforces 200 A Cinema]暴力,优化
标签:
原文地址:http://www.cnblogs.com/jklongint/p/4700889.html