CodeForces 761F. Dasha and Photos

Dasha decided to have a rest after solving the problem D and began to look photos from previous competitions.

Let's call photos as the matrix with the size n × m, which consists of lowercase English letters.

Some k photos especially interested her, because they can be received from photo-template by painting a rectangular area in a certain color. Let's call such photos special.

More formally the i-th special photo is received from the photo-template by replacing all characters on some rectangle with upper left corner of the cell with coordinates (ai, bi) and lower right corner in the cell with coordinates (ci, di) to the symbol ei.

Dasha asks you to find the special photo so that the total distance from it to all other special photos is minimum. And calculate this distance.

Determine the distance between two photos as the sum of distances between all corresponding letters. The distance between two letters is the difference module of their positions in the alphabet. For example, the distance between letters 'h' and 'm' equals |8 - 13| = 5, because the letter 'h' is the 8-th in the alphabet, the letter 'm' is the 13-th.

Input

The first line contains three integers nmk (1 ≤ n, m ≤ 103, 1 ≤ k ≤ 3·105) — the number of strings in the photo-template, the number of columns and the number of special photos which are interesting for Dasha.

The next n lines contains the string with m length which consists of little Latin characters — the description of the photo-template.

Each of the next k lines contains the description of the special photo in the following format, "ai bi ci di ei"(1 ≤ ai ≤ ci ≤ n, 1 ≤ bi ≤ di ≤ m), where (ai, bi) — is the coordinate of the upper left corner of the rectangle, (ci, di) — is the description of the lower right corner, and ei — is the little Latin letter which replaces the photo-template in the described rectangle.

Output

In the only line print the minimum total distance from the found special photo to all other special photos.

Examples
input
3 3 2
aaa
aaa
aaa
1 1 2 2 b
2 2 3 3 c
output
10
input
5 5 3
abcde
eabcd
deabc
cdeab
bcdea
1 1 3 4 f
1 2 3 3 e
1 3 3 4 i
output
59
Note

In the first example the photos are following:

bba    aaa
bba    acc
aaa    acc

The distance between them is 10.

题意:给一个基础n*m的小写字符串矩阵,和K个新矩阵

第i个矩阵把矩形(a[i],b[i],c[i],d[i])全部变成e[i]

定义两个字符的距离为它们之差

定义两个矩阵的距离是整个矩阵所有对应位置的字符距离之和

求一个新矩阵,让它到其他矩阵距离和最小,输出距离

题解:这题就是暴力...

我们只需要求出两个东西

p(i,j)表示所有新矩阵到原图距离前缀和,sum(x,i,j)表示全部替换成x之后到原图距离前缀和,然后乱搞。

复杂度O(26nm)

感谢http://blog.csdn.net/WorldWide_D/article/details/54807874的作者给我的题解!(怎么感觉代码基本就是变量名换了一下QAQ)

#include <bits/stdc++.h>

using namespace std;

const int MAXN = 1010;
const int MAXM = 300010;

long long ans = 1e16, s[26][MAXN][MAXN], p[MAXN][MAXN];

int cnt[26], sum[26][MAXN][MAXN], a[MAXM], b[MAXM], c[MAXM], d[MAXM], n, m, K;

char mp[MAXN][MAXN], e[MAXM];

inline long long cal(long long f[MAXN][MAXN], int i) { return f[ c[ i ] ][ d[ i ] ] - f[ a[ i ] - 1 ][ d[ i ] ] - f[ c[ i ] ][ b[ i ] - 1 ] + f[ a[ i ] - 1 ][ b[ i ] - 1 ]; }

int main()
{
	scanf( "%d%d%d", &n, &m, &K );
	for( int i = 1 ; i <= n ; i++ ) scanf( "%s", mp[ i ] + 1 );
	for( int i = 1 ; i <= K ; i++ )
	{
		scanf( "%d%d%d%d", &a[ i ], &b[ i ], &c[ i ], &d[ i ] );
		while( e[ i ] < 'a' || e[ i ] > 'z' ) e[ i ] = getchar();
		e[ i ] -= 'a';
		sum[ e[ i ] ][ a[ i ] ][ b[ i ] ]++;
		sum[ e[ i ] ][ a[ i ] ][ d[ i ] + 1 ]--;
		sum[ e[ i ] ][ c[ i ] + 1 ][ b[ i ] ]--;
		sum[ e[ i ] ][ c[ i ] + 1 ][ d[ i ] + 1 ]++;
	}
	for( int i = 1 ; i <= n ; i++ )
		for( int j = 1 ; j <= m ; j++ )
		{
			int tot = 0, ret = 0;
			for( int x = 0 ; x < 26 ; x++ )
			{
				cnt[ x ] = sum[ x ][ i ][ j ] += sum[ x ][ i - 1 ][ j ] + sum[ x ][ i ][ j - 1 ] - sum[ x ][ i - 1 ][ j - 1 ];
				ret += cnt[ x ];
				tot += cnt[ x ] * x;
			}
			cnt[ mp[ i ][ j ] - 'a' ] += K - ret;
			tot += ( K - ret ) * ( mp[ i ][ j ] - 'a' );
			for( int x = 0 ; x < 26 ; x++ )
			{
				if( x == mp[ i ][ j ] - 'a' ) p[ i ][ j ] = p[ i ][ j - 1 ] + p[ i - 1 ][ j ] - p[ i - 1 ][ j - 1 ] + tot;
				s[ x ][ i ][ j ] = s[ x ][ i - 1 ][ j ] + s[ x ][ i ][ j - 1 ] - s[ x ][ i - 1 ][ j - 1 ] + tot;
				if( x ) cnt[ x ] += cnt[ x - 1 ];
				tot += cnt[ x ] - ( K - cnt[ x ] );
			}
		}
	for( int i = 1 ; i <= K ; i++ )
		ans = min( ans, p[ n ][ m ] - cal( p, i ) + cal( s[ e[ i ] ], i ) );
	cout << ans << endl;
	return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值