2898终于过了(posted by biggates)
2006-07-24 22:22
417 查看
/**//*
Problem E:Entertainment
Time Limit:1000MS Memory Limit:65536K
Total Submit:29 Accepted:4
biggates 2898 Accepted 1184K 968MS C++ 8.23K 2006-07-24 14:12:13.0
Description
ACM-ICPC judges, sometimes, play computer games, such as Alphariz. In the game of Alphariz, you are given a table (e.g., Table I) of alphabetic characters. At each step of the game, you choose a table entry E containing a non-blank character ch. Then, you recursively identify all the friends of E. The friends are the existing table entries containing the same character ch which are located immediately to the left, right, up, and down directions of E, and their friends in turn, until no new friends can be located. Then, you replace the characters in E and its found friends with blanks. Table II shows the result of applying the latter rule on Table I, starting at entry E in row 1 and column 2, where ch is 'a'.
Then, while still in the same step, you shift all the non-blank characters to the left and the blanks to the right, as is shown in Table III. Next, you shift all non-blank characters down and the blanks are shifted up as is shown in Table IV. Note that possible full blank rows or columns are to be deleted.
You are to write a program that given the initial table and a sequence of selected table entries, apply the above rules for each given table entry, one after another, and report the final resulting table.
Input
The input consists of several test cases. Each test case starts with the character map which is given in m lines of height n characters (1 <= m, n <= 1000). Characters in the initial map are all lowercase letters. After this, there is a single line containing a single integer k which is the number of selected table entries, followed by k lines, containing two integers r (1 <= r <= m) and c (1 <= c <= n) which are the row and the column numbers of the table entry, respectively. Besides, the items are always inside the current table.
Output
The output for the ith test case should start with a line in the following format:
Test case #i:
After the first line, the final map should be written with the same format as in the input.
Sample Input
aabbb
abaab
aaaba
abbaa
1
1 2
aba
bbc
2
1 3
2 2
Sample Output
Test case #1:
bb
bb
bab
bbaa
Test case #2:
a
c
*/
#include<iostream>
#include<queue>
using namespace std;
const int MAX_LENGTH = 1001;
char data[MAX_LENGTH][MAX_LENGTH];
int char2int(char* ch)
...{
int temp = 0;
for(; *(ch) >= '0' && *(ch) <= '9'; ch++ )
...{
temp *= 10;
temp += *(ch) - '0';
}
return temp;
}
//removeFriends将位于X,Y处的字符以及与其相联的相同字符换成空格
void removeFriends(int X, int Y, char ch, const int& width, const int& height)
...{
if(X >= width || Y >= height || X * Y < 0)
return;
data[Y][X] = ' ';
if(X > 0 && data[Y][X - 1] == ch)
...{
removeFriends(X - 1, Y, ch, width, height);
}
if(X < width && data[Y][X + 1] == ch)
...{
removeFriends(X + 1, Y, ch, width, height);
}
if(Y > 0 && data[Y - 1][X] == ch)
...{
removeFriends(X, Y - 1, ch, width, height);
}
if(Y < height && data[Y + 1][X] == ch)
...{
removeFriends(X, Y + 1, ch, width, height);
}
}
/**//*
tide()将整个表规整好,并移动到左上角,并改变相应的width和height值
注意:width和height均不是数组下标,从1开始计数
规整的方法是:
0. 原始表(width, height)
1. 将所有元素向左边移动,同时统计最宽的一行maxX和每列的元素数countY(maxX + 1, height)
2. 将所有元素向下移动,同时统计最宽的一行maxX和最大的列元素数minY和maxY(maxX + 1, height)
3. 将所有元素向上移动(maxX + 1, maxY - minY + 1)
4. 将后面所有元素置0 横坐标范围(maxX + 1, width), 纵坐标范围(maxY - minY, height)
5. 修改width和height的值
*/
void tide(int& width, int& height)
...{
int X = 0;
int Y = 0;
int len = 0;
int minX = width;
int maxX = 0; //X从0开始计数
int minY = height; //Y从1开始计数
int maxY = 0;
int countY[MAX_LENGTH]; //countY[Y]为第Y列(数组下标)的元素数
memset(countY, 0, sizeof(countY));
/**//*
for(Y = 0; Y < height; Y++)
{
len = 0;
for(X = 0; X < width; X++)
{
if(data[Y][X] != ' ' && data[Y][X] != 0)
{
if(X < minX)
{
minX = X;
}
if(X > maxX)
{
maxX = X;
}
if(Y < minY)
{
minY = Y;
}
if(Y > maxY)
{
maxY = Y;
}
//定位maxX、maxY、minY、minX
data[Y][len] = data[Y][X];
countY[len++] ++;
}
if(len != X + 1)
data[Y][X] = ' ';
}
}
for(Y = 0; Y < maxX; Y++)
{
if(maxY < countY[Y])
maxY = countY[Y];
}
width = maxX + 1;
height = maxY;
for(X = 0; X < width; X++)
{
minY = 0;
for(Y = 0; Y < maxY; Y++)
{
if(countY[X] == height)
continue;
if(data[maxY - Y - 1][X] != ' ' && data[Y][X] != 0)
{
if(minY == 0 )
{
minY++;
continue;
}
data[maxY - minY - 1][X] = data[maxY - Y - 1][X];
minY ++;
}
data[maxY - Y - 1][X] = ' ';
}
}
int test = 0;
for(Y = 0; Y < width; Y++)
{
test = 0;
for(X = 0; X < height; X++)
{
test += (data[Y][X] % ' ');
}
if(test == 0)
{
for(test = Y; test < height; test++)
{
strcpy(data[test] , data[test+1]);
}
//height--;
}
}
*/
for(Y = 0; Y < height; Y++)
...{
len = 0; //每一行开始时,设临时计数器len = 0。表示当前行的第len个非零元素应该被放到的位置
for(X = 0; X < width; X++)
...{
if( data[Y][X] == 0)
...{
break; //当前行已结束,转下一行
}
if( data[Y][X] != ' ' )
...{
if(maxX < X)
...{
maxX = X; //统计maxX
}
countY[X] ++; //统计countY
if(len == X)
...{
len++; //若前面都是满的,则继续看下一个
continue;
}
data[Y][len] = data[Y][X];
data[Y][X] = ' ';
len++;
}
}
}
//完成1
minX = 0;
for(X = 0; X < maxX + 1; X++)
...{
len = height - 1; //每一列开始时,设临时计数器len = height,表示当前列从下往上数的第len个非零元素应该被放到的位置
for(Y = height - 1; Y >= 0; Y--)
...{
if(data[Y][X] == 0)
...{
break; //当前行已结束,转下一行
}
if( data[Y][X] != ' ')
...{
if(minX < X)
...{
minX = X; //统计maxX(先用minX存放)
}
if(len == Y)
...{
len--;
continue;
}
data[len][X] = data[Y][X];
data[Y][X] = ' ';
len--;
}
}
}
//完成2
maxX = minX;
maxY = 0;
minY = height;
for(X = 0; X < maxX + 1; X++)
...{
for(Y = height - 1; Y >= 0; Y--)
...{
if(data[Y][X] == 0)
...{
break; //当前行已结束,转下一行
}
if( data[Y][X] != ' ')
...{
if(minY > Y)
...{
minY = Y; //统计minY
}
if(maxY < Y)
...{
maxY = Y; //统计maxY
}
}
}
}
//统计minY和maxY
for(len = 0; len < maxY - minY + 1; len++)
...{
strcpy(data[len], data[minY + len]);
}
//完成3
for(len = maxX + 1; len < width; len ++)
...{
for(minX = 0; minX < height; minX ++)
...{
data[minX][len] = 0;
}
}
//清除右边的空列
for(len = maxY - minY + 1; len < height; len++)
...{
for(minX = 0; minX < maxX; minX++)
...{
data[len][minX] = 0;
}
}
//清除下边的空行
//完成4
width = maxX + 1;
height = maxY - minY + 1;
//完成5
}
void printmap(const int width, const int height)
...{
if(data[0][0] == 0)
...{
return;
}
int i = 0;
int j = 0;
for(i = 0; i < height; i++)
...{
for(j = 0; j < width; j++)
...{
cout << data[i][j];
}
cout << endl;
}
}
int main()
...{
int height = 0;
int width = 0;
char buffer [MAX_LENGTH];
int times = 0;
int x = 0;
int y = 0;
int friendcount = 0;
do
...{
//times = 0;
height = 0;
memset(data, 0, sizeof(data));
times++;
do
...{
cin.clear(ios::goodbit);
cin.getline(buffer, MAX_LENGTH);
if(buffer[0] == 0)
cin.getline(buffer, MAX_LENGTH);
if(buffer[0] == 0)
return 0;
if( !isalpha(buffer[0]))
...{
break;
}
strcpy( data[height++],buffer);
width = strlen(buffer);
}
while( isalpha(buffer[0]));
//以上将原始信息输入到data
friendcount = char2int(buffer);
for(; friendcount > 0; friendcount --)
...{
cin >> y >> x;
removeFriends(x-1, y-1, data[y - 1][x - 1], width, height);
tide(width, height);
}
cout << "Test case #" << times << ':' << endl;
printmap(width, height);
}
while(strlen(buffer) > 0);
return 0;
}
相关文章推荐
- 《向着夕阳,挥洒青春的泪水》系列正式开始连载! (posted by biggates)
- ACMManager 1.0.3 版本历史(posted by biggates)
- 语法着色! ACMManager新功能?(posted by biggates)
- ACMManager 1.0.4 新功能(posted by biggates)
- pku 1007 一次AC(posted by biggates)
- ACMManager Beta 预览(posted by biggates)
- ACMManager 1.0.3版本最新报道(posted by biggates)
- VINS_Mono,OpenCV Error: Bad argument (Invalid pointer to file storage) in cvGetFileNodeByName问题终于解决了
- 第8章第16题的完整程序(Powered by biggates)
- Posted on December 23, 2008, 1:55 pm, by Alexander Sandler, under Programming Articles. Table of
- Cool Tips and Tricks with ASP.NET 2.0 posted by Scott
- 117 Posted by seenagape on June 23, 2012 Leave a comment (0) Go to comments The BACKUP_TAPE_IO_SLAVE
- 终于搞定了!![by beabsolutezero]
- 第8章第11题的完整程序(Powered by biggates)
- REST APIs must be hypertext-driven——Posted by Roy T. Fielding
- Column AND Row Posted by David Dobrin
- 熬人的日子终于结束了[by beabsolutezero]
- 第11章第15题完整代码(cpp) (Powered by biggates)
- 产品管理的前世今生-前世篇(含前言)--Posted by ucpm
- 第10章第16题完整代码(cpp) (Powered by biggates)