pku 1175 Starry Night
题目地址:http://acm.pku.edu.cn/JudgeOnline/problem?id=1175
题目大意:
就是给你一个图,你必须按照从左到右,从上到下的顺序对每块联通块进行编号,并且按照编号的字典序,把每个连通块变成
'a' + number (number从0开始的图案)
详细分析:
由于做的时间离现在有点久,博主以后会对这个系列的题进行详细分析。
AC代码:
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<cmath>
using namespace std;
#define N 105
#define eps 1e-9
struct Node
{
int x;
int y;
}s[N*N];
int w,h,cnt = 0,num =0;
char Map[N][N];
int dirc[8][2] = {{1,-1},{1,0},{1,1},{0,1},{0,-1},{-1,0},{-1,1},{-1,-1}};
int vis[N][N];
double ans[N*5] ;
int sgn(double x)
{
return x < -eps? -1: x < eps? 0: 1;
}
void cal()
{
double sum = 0;
for(int i = 0 ;i < cnt; i++ )
for(int j = i + 1; j < cnt ;j++ )
{
sum += sqrt((s[i].x - s[j].x)*(s[i].x - s[j].x)*1.0 + (s[i].y - s[j].y)*(s[i].y - s[j].y)*1.0);
}
if(cnt == 1)
sum = 0.0;
//cout << "sum is :" << sum << endl;
int temp = -1 ;
for(int i= 0; i < num ;i++)
{
if(sgn(ans[i] - sum) == 0)
{
temp = i;
break;
}
}
if(temp == -1)
{
temp = num;
ans[num++] = sum;
}
for(int i = 0; i < cnt ;i++ )
{
Map[s[i].x][s[i].y] = 'a' + temp;
}
}
int Find_union(int pos_x, int pos_y)
{
vis[ pos_x ][ pos_y ] = 1;
int sum = 0;
Node temp;
temp.x = pos_x;
temp.y = pos_y;
s[ cnt++ ] = temp;
for(int i = 0 ;i < 8; i++)
{
int temp_x = pos_x + dirc[i][0];
int temp_y = pos_y + dirc[i][1];
if(temp_x >=0 && temp_x < h && temp_y >=0 && temp_y < w && Map[temp_x][temp_y] == '1' && !vis[temp_x][temp_y])
{
sum ++;
sum += Find_union(temp_x, temp_y);
}
}
return sum;
}
int main()
{
while(cin >> w >> h)
{
for(int i = 0 ;i < h ; i++ )
for(int j = 0 ;j < w ; j++ )
cin >> Map[i][j];
memset(vis, 0, sizeof(vis));
int order = 0;
for(int i = 0; i < h ;i++ )
for(int j = 0 ; j < w ;j++ )
if(!vis[i][j] && Map[i][j] =='1')
{
cnt = 0;
Find_union( i, j );
order++ ;
cal();
}
//cout << "------------------------------" << endl;
for(int i = 0 ;i < h ; i++ )
{
for(int j = 0 ;j < w ; j++ )
cout << Map[i][j];
cout << endl;
}
}
return 0;
}