2012年每周一赛第二场第三题。看完题目大家都想到的那个办法肯定会超时,复杂度是O(MN)。仔细思考可以发现,其实我们关心的只是每次移动后,在X轴和Y轴上分别靠近和远离了多少个点,两者差值就是靠近或是远离了多少距离。所以,我们只需要确定x和y为某值时会靠近和远离多少个点即可,我是使用了upper_bound和lower_bound这两个函数,复杂度是O(Mlog2N)。
Run Time: 0.37sec
Run Memory: 964KB
Code Length: 953Bytes
Submit Time: 2012-03-04 20:17:54
// Problem#: 4875
// Submission#: 1233302
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// URI: http://creativecommons.org/licenses/by-nc-sa/3.0/
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <cstdio>
#include <algorithm>
using namespace std;
inline int abs( int n ) { return n > 0 ? n: -n; }
int main()
{
int N, M;
int X[ 100000 ], Y[ 100000 ];
char c;
long long dist = 0;
scanf( "%d%d", &N, &M );
for ( int i = 0; i < N; i++ ) {
scanf( "%d%d", &X[ i ], &Y[ i ] );
dist += abs( X[ i ] ) + abs( Y[ i ] );
}
sort( X, X + N );
sort( Y, Y + N );
int x = 0, y = 0;
getchar();
for ( int i = 1; i <= M; i++ ) {
scanf( "%c", &c );
if ( c == 'S' )
dist += 2 * ( upper_bound( Y, Y + N, y++ ) - Y ) - N;
else if ( c == 'J' )
dist -= 2 * ( lower_bound( Y, Y + N, y-- ) - Y ) - N;
else if ( c == 'I' )
dist += 2 * ( upper_bound( X, X + N, x++ ) - X ) - N;
else if ( c == 'Z' )
dist -= 2 * ( lower_bound( X, X + N, x-- ) - X ) - N;
printf( "%lld\n", dist );
}
return 0;
}