UVa 10336 - Rank the Languages ( DFS )
题意
各国语言统计, 类似连通块, 但只有上下左右四个方向, 斜对角不算连通
最后按照语言使用人数按照从大到小排序输出, 人数相等的按照字典序输出
思路
只走上下左右四个方向的DFS连通块 用一个abs就能巧妙转化
for( int dx = -1; dx <= 1; dx++ ){
for( int dy = -1; dy <= 1; dy++ ){
if( abs(dx+dy) != 1 ) continue;
}
}
用结构体存下语言代号及人数, 用结构体排序即可
bool cmp( struct MAP a, struct MAP b )
{
if( a.x == b.x )
return a.c < b.c;
return a.x > b.x;
}
AC代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <cmath>
using namespace std;
int m, n;
int alp[30];
char mrk[30];
char s[50][50];
struct MAP{
char c;
int x;
};
struct MAP p[30];
bool cmp( struct MAP a, struct MAP b )
{
if( a.x == b.x )
return a.c < b.c;
return a.x > b.x;
}
void dfs( int x, int y, char a )
{
s[x][y] = '0';
for( int dx = -1; dx <= 1; dx++ ){
for( int dy = -1; dy <= 1; dy++ ){
if( abs(dx+dy) != 1 ) continue;
int nx = x + dx, ny = y + dy;
if( nx >= 0 && nx < m && ny >= 0 && ny < n && s[nx][ny] == a )
dfs( nx, ny, a );
}
}
return;
}
void solve( char a, int k )
{
int num = 0;
for( int i = 0; i < m; i++ ){
for( int j = 0; j < n; j++ ){
if( s[i][j] == a ){
dfs(i,j,a);
num++;
}
}
}
p[k].c = a, p[k].x = num;
}
int main()
{
int T, kase = 0;
scanf("%d",&T);
while(T--){
int num = 0;
memset(s,0,sizeof(s));
memset(alp,0,sizeof(alp));
memset(mrk,0,sizeof(mrk));
scanf("%d%d",&m,&n);
getchar();
for( int i = 0; i < m; i++ ){
for( int j = 0; j < n; j++ ){
scanf("%c",&s[i][j]);
if( !alp[s[i][j] - 'a'] ){
alp[s[i][j] - 'a'] = 1;
mrk[num] = s[i][j];
num++;
}
}
getchar();
}
printf("World #%d\n",++kase);
for( int i = 0; i < num; i++ )
solve( mrk[i], i );
sort( p, p+num, cmp );
for( int i = 0; i < num; i++ )
printf("%c: %d\n",p[i].c, p[i].x);
}
return 0;
}