一 原题
IOI 98
High up in the night sky, the shining stars appear in clusters ofvarious shapes. Acluster is a non-empty group of neighbouringstars, adjacent in horizontal, vertical or diagonal direction. A clustercannot be a part of a larger cluster.
Clusters may be similar. Two clusters are similar if they havethe same shape and number of stars, irrespective of their orientation.In general, the number of possible orientations for a cluster is eight,as Figure 1 exemplifies.
Figure 1. Eight similar clusters
The night sky is represented by a sky map, which is a two-dimensionalmatrix of 0's and 1's. A cell contains the digit 1 if it has a star,and the digit 0 otherwise.
Given a sky map, mark all the clusters with lower case letters.Similar clusters must be marked with the same letter; non-similarclusters must be marked with different letters.
You mark a cluster with a lower case letter by replacing every 1 inthe cluster by that lower case letter.
PROGRAM NAME: starry
INPUT FORMAT
The first two lines contain, respectively, the width W andthe heightH of a sky map. The sky map is given in the followingH lines, ofW characters each.
SAMPLE INPUT (file starry.in)
23
15
10001000000000010000000
01111100011111000101101
01000000010001000111111
00000000010101000101111
00000111010001000000000
00001001011111000000000
10000001000000000000000
00101000000111110010000
00001000000100010011111
00000001110101010100010
00000100110100010000000
00010001110111110000000
00100001110000000100000
00001000100001000100101
00000001110001000111000
In this case, the sky map has width 23 and height 15. Just to make itclearer, notice that this input file corresponds to the followingpicture of the sky.
Figure 2. Picture of the sky
OUTPUT FORMAT
The output file contains the same map as the input file, except thatthe clusters are marked as described in Task.
There will generally be more than one way to label the clusters withletters. Your program should choose the labeling such that if theentire output file is read as a string, this string will be minimal inthe lexicographical ordering.
SAMPLE OUTPUT (file starry.out)
a000a0000000000b0000000
0aaaaa000ccccc000d0dd0d
0a0000000c000c000dddddd
000000000c0b0c000d0dddd
00000eee0c000c000000000
0000e00e0ccccc000000000
b000000e000000000000000
00b0f000000ccccc00a0000
0000f000000c000c00aaaaa
0000000ddd0c0b0c0a000a0
00000b00dd0c000c0000000
000g000ddd0ccccc0000000
00g0000ddd0000000e00000
0000b000d0000f000e00e0b
0000000ddd000f000eee000
This is one possible result for the sample input above. Notice that thisoutput file corresponds to the following picture.
Figure 3. Picture with the clusters marked
Constraints
0 <= W (width of the sky map) <= 1000 <= H (height of the sky map) <= 100
0 <= Number of clusters <= 500
0 <= Number of non-similar clusters <= 26 (a..z)
1 <= Number of stars per cluster <= 160
二 分析
水水的I。先求出所有的联通块,再判断联通块是否形状相同。
三 代码
运行结果:
USER: Qi Shen [maxkibb3] TASK: starry LANG: C++ Compiling... Compile: OK Executing... Test 1: TEST OK [0.000 secs, 4252 KB] Test 2: TEST OK [0.000 secs, 4252 KB] Test 3: TEST OK [0.000 secs, 4252 KB] Test 4: TEST OK [0.000 secs, 4252 KB] Test 5: TEST OK [0.000 secs, 4252 KB] All tests OK.
YOUR PROGRAM ('starry') WORKED FIRST TIME! That's fantastic -- and a rare thing. Please accept these special automated congratulations.
AC代码:
/*
ID:maxkibb3
LANG:C++
PROB:starry
*/
#include<cstdio>
#include<vector>
#include<algorithm>
using namespace std;
const int MAXH = 105;
const int MAXW = 105;
const int MAXC = 505;
int H, W;
char Map[MAXH][MAXW];
int Vis[MAXH][MAXW];
int Cluster_num;
int Flag[MAXC];
int Flag_num;
int dx[8][2] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, -1},
{0, 1}, {1, -1}, {1, 0}, {1,1}};
struct Coor {
int x, y;
bool operator < (const Coor &obj) const {
if(obj.x == x) return y < obj.y;
return x < obj.x;
}
bool operator == (const Coor &obj) const {
if(x != obj.x || y != obj.y) return false;
else return true;
}
Coor operator - (const Coor &obj) const {
Coor ret;
ret.x = x - obj.x;
ret.y = y - obj.y;
return ret;
}
};
Coor mk_coor(int _x, int _y) {
Coor ret;
ret.x = _x, ret.y = _y;
return ret;
}
struct Cluster {
vector<Coor> stars;
bool operator == (const Cluster &obj) const {
if(stars.size() != obj.stars.size()) return false;
Coor delta = stars[0] - obj.stars[0];
for(int i = 1; i < stars.size(); i++) {
Coor tmp = stars[i] - obj.stars[i];
if(tmp == delta) continue;
else return false;
}
return true;
}
Cluster rotate() {
Cluster ret;
for(int i = 0; i < stars.size(); i++)
ret.stars.push_back(mk_coor(stars[i].y, -stars[i].x));
return ret;
}
Cluster flip() {
Cluster ret;
for(int i = 0; i < stars.size(); i++)
ret.stars.push_back(mk_coor(stars[i].x, -stars[i].y));
return ret;
}
void star_sort() {
sort(stars.begin(), stars.end());
}
}Clusters[MAXC];
void init() {
scanf("%d%d", &W, &H);
for(int i = 0; i < H; i++)
scanf("%s", Map[i]);
}
void dfs(int _x, int _y) {
Vis[_x][_y] = Cluster_num;
Clusters[Cluster_num - 1].stars.push_back(mk_coor(_x, _y));
for(int i = 0; i < 8; i++) {
int x = _x + dx[i][0];
int y = _y + dx[i][1];
if(x < 0 || x >= H || y < 0 || y >= W)
continue;
if(Map[x][y] == '0')
continue;
if(Vis[x][y] != 0)
continue;
dfs(x, y);
}
}
void lable() {
for(int i = 0; i < H; i++)
for(int j = 0; j < W; j++) {
if(Vis[i][j] != 0) continue;
if(Map[i][j] == '0') continue;
Cluster_num++;
dfs(i, j);
}
}
void merge() {
for(int i = 0; i < MAXC; i++) Flag[i] = -1;
for(int i = 0; i < Cluster_num; i++) {
if(Flag[i] != -1) continue;
Flag[i] = Flag_num++;
vector<Cluster> c;
Cluster base = Clusters[i];
for(int j = 0; j < 4; j++) {
base.star_sort();
c.push_back(base);
Cluster tmp = base.flip();
tmp.star_sort();
c.push_back(tmp);
base = base.rotate();
}
for(int j = i + 1; j < Cluster_num; j++) {
if(Flag[j] != -1) continue;
for(int k = 0; k < 8; k++) {
if(Clusters[j] == c[k]) {
Flag[j] = Flag[i];
break;
}
}
}
}
for(int i = 0; i < Cluster_num; i++) {
Cluster c = Clusters[i];
for(int j = 0; j < c.stars.size(); j++) {
Map[c.stars[j].x][c.stars[j].y] = (char)('a' + Flag[i]);
}
}
for(int i = 0; i < H; i++) {
for(int j = 0; j < W; j++) printf("%c", Map[i][j]);
printf("\n");
}
}
void solve() {
lable();
merge();
}
int main() {
freopen("starry.in", "r", stdin);
freopen("starry.out", "w", stdout);
init();
solve();
return 0;
}