我正在练习编程竞赛,我可以选择使用Python或C ++来解决每个问题,所以我对任何一种语言的解决方案持开放态度 - 无论哪种语言最适合这个问题。
我遇到的过去问题的网址是http://progconz.elena.aut.ac.nz/attachments/article/74/10%20points%20Problem%20Set%202012.pdf,问题F(“地图”)。
基本上它涉及匹配一大块ASCII艺术品的出现。在C ++中,我可以为每一段ASCII艺术创建一个向量。问题是当较小的部分是多行时如何匹配它。
我不知道如何去做。我不希望为我编写所有代码,只是想知道问题所需的逻辑。
感谢您的帮助。
这是我到目前为止所得到的:
#include <cstdlib>
#include <iostream>
#include <string>
#include <algorithm>
#include <vector>
using namespace std;
int main( int argc, char** argv )
{
int nScenarios, areaWidth, areaHeight, patternWidth, patternHeight;
cin >> nScenarios;
for( int a = 0; a < nScenarios; a++ )
{
//get the pattern info and make a vector
cin >> patternHeight >> patternWidth;
vector< vector< bool > > patternIsBuilding( patternHeight, vector<bool>( patternWidth, false ) );
//populate data
for( int i = 0; i < patternHeight; i++ )
{
string temp;
cin >> temp;
for( int j = 0; j < patternWidth; j++ )
{
patternIsBuilding.at( i ).at( j ) = ( temp[ j ] == 'X' );
}
}
//get the area info and make a vector
cin >> areaHeight >> areaWidth;
vector< vector< bool > > areaIsBuilding( areaHeight, vector<bool>( areaWidth, false ) );
//populate data
for( int i = 0; i < areaHeight; i++ )
{
string temp;
cin >> temp;
for( int j = 0; j < areaWidth; j++ )
{
areaIsBuilding.at( i ).at( j ) = ( temp[ j ] == 'X' );
}
}
//now the vectors contain a `true` for a building and a `false` for snow
//need to find the matches for patternIsBuilding inside areaIsBuilding
//how?
}
return 0;
}
编辑:从下面的评论我已经从J.F. Sebastian
获得了Python的解决方案。它有效,但我不明白。我已经评论了我能做什么,但需要帮助理解return
函数中的count_pattern
语句。
#function to read a matrix from stdin
def read_matrix():
#get the width and height for this matrix
nrows, ncols = map( int, raw_input().split() )
#get the matrix from input
matrix = [ raw_input() for _ in xrange( nrows ) ]
#make sure that it all matches up
assert all(len(row) == ncols for row in matrix)
#return the matrix
return matrix
#perform the check, given the pattern and area map
def count_pattern( pattern, area ):
#get the number of rows, and the number of columns in the first row (cause it's the same for all of them)
nrows = len( pattern )
ncols = len( pattern[0] )
#how does this work?
return sum(
pattern == [ row[ j:j + ncols ] for row in area[ i:i + nrows ] ]
for i in xrange( len( area ) - nrows + 1 )
for j in xrange( len( area[i] ) - ncols + 1 )
)
#get a number of scenarios, and that many times, operate on the two inputted matrices, pattern and area
for _ in xrange( int( raw_input() ) ):
print count_pattern( read_matrix(), read_matrix() )
答案 0 :(得分:1)
不要以线条来思考。将整个页面读成一个字符串,并像对待任何其他字符一样处理行尾字符。
(你可能认为这是一个神秘的暗示,但你确实要求“一个想法”如何去做。)
编辑:由于你知道图片的整体尺寸,你可以从你想要匹配的图案的第一行开始向前计算字符,以便匹配第二行,等等以后续行。
答案 1 :(得分:1)
#how does this work?
return sum(
pattern == [ row[ j:j + ncols ] for row in area[ i:i + nrows ] ]
for i in xrange( len( area ) - nrows + 1 )
for j in xrange( len( area[i] ) - ncols + 1 )
)
可以使用显式的for-loop块重写生成器表达式:
count = 0
for i in xrange( len( area ) - nrows + 1 ):
for j in xrange( len( area[i] ) - ncols + 1 ):
count += (pattern == [ row[ j:j + ncols ]
for row in area[ i:i + nrows ] ])
return count
比较(pattern == ..
)在Python中返回等于1/0的True / False。
构建子矩阵以与模式进行比较的列表理解可以优化以更早返回:
count += all(pattern_row == row[j:j + ncols]
for pattern_row, row in zip(pattern, area[i:i + nrows]))
或者使用显式的for-loop块:
for pattern_row, row in zip(pattern, area[i:i + nrows]):
if pattern_row != row[j:j + ncols]:
break # no match (the count stays the same)
else: # matched (no break)
count += 1 # all rows are equal
答案 2 :(得分:0)
#include <iostream>
#include <vector>
using namespace std;
int main(){
int numOfRounds;
cin >> numOfRounds;
for(int round = 0; round < numOfRounds; round++){
int out = 0;
int linesToMatch;
cin >> linesToMatch;
int sizeToMatch;
cin >> sizeToMatch;
vector <string> v;
string t;
for (int i = 0; i < linesToMatch; i++){
cin >> t;
v.push_back(t);
}
string s = "";
int rows;
cin >> rows;
int columns;
cin >> columns;
for (int j = 0; j < rows; j++){ //map->string
cin >> t;
s += t;
}
// main part of implementation
// it's mainly basic algebra and index tracking
for (int m = 0; m <= rows - linesToMatch; m++){
for (int n = 0; n <= columns - sizeToMatch; n++){
int x;
for (x = 0; x < linesToMatch; x++){
int index = (m + x) * columns + n;
string newTemp(s.begin() + index, s.begin() + index + sizeToMatch);
if (newTemp != v.at(x)) break;
}
if (x == linesToMatch) out++;
}
}
cout << out << endl;
}
}