poj2585 Window Pains

這是題目:

3:Window Pains
查看 提交 統計 提問
總時間限制: 1000ms 內存限制: 65536kB
描述
Boudreaux likes to multitask, especially when it comes to using his computer. Never satisfied with just running one application at a time, he usually runs nine applications, each in its own window. Due to limited screen real estate, he overlaps these windows and brings whatever window he currently needs to work with to the foreground. If his screen were a 4 x 4 grid of squares, each of Boudreaux's windows would be represented by the following 2 x 2 windows:
1 1 . .
1 1 . .
. . . .
. . . .
. 2 2 .
. 2 2 .
. . . .
. . . .
. . 3 3
. . 3 3
. . . .
. . . .
. . . .
4 4 . .
4 4 . .
. . . .
. . . .
. 5 5 .
. 5 5 .
. . . .
. . . .
. . 6 6
. . 6 6
. . . .
. . . .
. . . .
7 7 . .
7 7 . .
. . . .
. . . .
. 8 8 .
. 8 8 .
. . . .
. . . .
. . 9 9
. . 9 9
When Boudreaux brings a window to the foreground, all of its squares come to the top, overlapping any squares it shares with other windows. For example, if window 1and then window 2 were brought to the foreground, the resulting representation would be:
1 2 2 ?
1 2 2 ?
? ? ? ?
? ? ? ?
If window 4 were then brought to the foreground:
1 2 2 ?
4 4 2 ?
4 4 ? ?
? ? ? ?
. . . and so on . . .
Unfortunately, Boudreaux's computer is very unreliable and crashes often. He could easily tell if a crash occurred by looking at the windows and seeing a graphical representation that should not occur if windows were being brought to the foreground correctly. And this is where you come in . . .
輸入
Input to this problem will consist of a (non-empty) series of up to 100 data sets. Each data set will be formatted according to the following description, and there will be no blank lines separating data sets.

A single data set has 3 components:
Start line - A single line:
START

Screen Shot - Four lines that represent the current graphical representation of the windows on Boudreaux's screen. Each position in this 4 x 4 matrix will represent the current piece of window showing in each square. To make input easier, the list of numbers on each line will be delimited by a single space.
End line - A single line:
END

After the last data set, there will be a single line:
ENDOFINPUT

Note that each piece of visible window will appear only in screen areas where the window could appear when brought to the front. For instance, a 1 can only appear in the top left quadrant.
輸出
For each data set, there will be exactly one line of output. If there exists a sequence of bringing windows to the foreground that would result in the graphical representation of the windows on Boudreaux's screen, the output will be a single line with the statement:

THESE WINDOWS ARE CLEAN

Otherwise, the output will be a single line with the statement:
THESE WINDOWS ARE BROKEN

樣例輸入
START
1 2 3 3
4 5 6 6
7 8 9 9
7 8 9 9
END
START
1 1 3 3
4 1 3 3
7 7 9 9
7 7 9 9
END
ENDOFINPUT

樣例輸出
THESE WINDOWS ARE CLEAN
THESE WINDOWS ARE BROKEN

來源
South Central USA 2003

===================================================================================================================

拓撲排序。在某個程序p的位置上若出現其他程序(如a, b, c, d)的標號,那麼其他程序一定在p之後運行(若不然...),由此可得有向邊(p-->a), (p-->b), (p-->c), (p-->d),掃描輸入矩陣,即可構圖。若正常,則這個圖是DAG,所有頂點可以排成一個拓撲序列;若不正常,則圖中有環(p不可能既在a之前,又在a之後運行),因此不是所有頂點都可以排成一個拓撲序列。


代碼清單:

#include <iostream>
#include <string>
#include <stack>	//用於實現拓撲排序:存儲入度爲0的頂點
using namespace std;

#define WINSZ 4
#define BLOCKSZ 2
#define MAXVERTEX 9
#define INFINITE 999999999
#define CONNECTED 1

int adjMatrix[MAXVERTEX][MAXVERTEX];	//鄰接矩陣
int inDegree[MAXVERTEX];	//入度表

void init()
{
	for (int i=0; i<MAXVERTEX; ++i)
	{
		inDegree[i]=0;

		for (int j=0; j<MAXVERTEX; ++j)
		{
			adjMatrix[i][j]=INFINITE;
		}
	}
}

void buildGraph(int m[][WINSZ])
{
	int x, y;	//每一程序塊左上角點在矩陣中的座標
	int dx, dy;	//用於遍歷一個程序塊中的數字
	int current;

	for (int i=0; i<MAXVERTEX; ++i)
	{
		x=i%(WINSZ-1);
		y=i/(WINSZ-1);

		for (dy=0; dy<BLOCKSZ; ++dy)
		{
			for (dx=0; dx<BLOCKSZ; ++dx)
			{
				current=m[y+dy][x+dx];

				if(current!=i && adjMatrix[i][current]==INFINITE)	//在程序塊i中出現的其他程序塊current只能在i之後,即,有邊(i-->current)。另外注意不要重複計算入度。
				{
					adjMatrix[i][current]=CONNECTED;
					++inDegree[current];
				}
			}
		}
	}		
}

bool toposortable()	//所有頂點是否可形成一個拓撲序列。如果有環,當然不能形成拓撲序列。
{
	stack<int> zeroInD;
	for (int i=0; i<MAXVERTEX; ++i)
	{
		if(inDegree[i]==0)
		{
			zeroInD.push(i);
		}
	}

	while (!zeroInD.empty())
	{
		int current=zeroInD.top();
		zeroInD.pop();

		for (int i=0; i<MAXVERTEX; ++i)
		{
			if (adjMatrix[current][i] == CONNECTED)	//發現一條以current爲起點的有向邊
			{
				--inDegree[i];	//刪掉這條邊,終點的入度-1
				if(inDegree[i] == 0)
				{
					zeroInD.push(i);
				}
			}
		}
	}

	//檢查拓撲序列是否包含了所有的頂點,因爲若有環,環上的頂點絕不可能在拓撲序列中。
	//檢查最終是否所有頂點的入度都減爲0。若有頂點入度不爲0,說明不在拓撲序列中。
	for (int i=0; i<MAXVERTEX; ++i)
	{
		if (inDegree[i] != 0)
		{
			return false;
		}
	}

	return true;
}

int main()
{
	freopen("D:\\in.txt", "r", stdin);
	freopen("D:\\out.txt", "w", stdout);

	int inputMat[WINSZ][WINSZ];

	string tempStr;
	int tempInt;

	while (1)
	{
		cin>>tempStr;

		if(tempStr == "ENDOFINPUT")	break;

		for (int i=0; i<WINSZ; ++i)
		{
			for (int j=0; j<WINSZ; ++j)
			{
				cin>>tempInt;
				inputMat[i][j]=tempInt-1;
			}
		}

		init();
		buildGraph(inputMat);
		if (toposortable())	cout<<"THESE WINDOWS ARE CLEAN"<<endl;
		else cout<<"THESE WINDOWS ARE BROKEN"<<endl;

		cin>>tempStr;
	}

	return 0;
}


發佈了50 篇原創文章 · 獲贊 16 · 訪問量 11萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章