2016藍橋杯省賽C/C++B組7題剪郵票 for循環暴力+bfs判斷聯通

剪郵票


如【圖1.jpg】, 有12張連在一起的12生肖的郵票。
現在你要從中剪下5張來,要求必須是連着的。
(僅僅連接一個角不算相連)
比如,【圖2.jpg】,【圖3.jpg】中,粉紅色所示部分就是合格的剪取。

請你計算,一共有多少種不同的剪取方法。


思路:

    沒錯,一開始我傻到寫了個暴搜,天真的以爲每個重複了五次,除以5即可...mmp,後來纔想起來....

    因爲每個位置每次所走的方向不一樣也會導致同一個解,這就導致每一個重複次數不確定,所以GG。

    因爲只需找五個,而且還是填空題,我們可以五層for找到五個點(當然暴搜好像更方便代碼更簡潔啊),BFS判斷一下五個點是否聯通即可(這裏因爲想找到所有情況一下子判斷有點難,乾脆搜索吧)


最後答案116


#include <bits/stdc++.h>

using namespace std;

int a[10];
int Go[4][2] = {0,1,1,0,0,-1,-1,0};
bool check()
{
	int book[30];
	memset(book,0,sizeof book);
	for(int i = 1;i <= 5;++i)
		book[a[i]] = 1;
	queue<int>Q;
	while(!Q.empty()) Q.pop();
	bool vis[30];
	memset(vis,0,sizeof vis);
	vis[a[1]] = 1;
	Q.push(a[1]);
	while(!Q.empty())
	{
		int cur = Q.front();Q.pop();
		int x = (cur-1) /4;int y = (cur - 1)% 4;
		for(int i = 0;i < 4;++i)
		{

			int tx = x + Go[i][0];
			int ty = y + Go[i][1];
			int nxt = tx * 4 + ty + 1;
			if(tx >= 0 && tx < 3 && ty >= 0 && ty < 4 && !vis[nxt] && book[nxt])
			{
				vis[nxt] = 1;
				Q.push(nxt);
			}
		}
	}
	for(int i = 1;i <= 5;++i)
		if(vis[a[i]] == 0)
			return 0;
	return 1;
}
int main()
{
	int ans = 0;
	for(int i = 1;i <= 12;++i)
	{
		a[1] = i;
		for(int j = i + 1;j <= 12;++j)
		{
			a[2] = j;
			for(int k = j + 1;k <= 12;++k)
			{
				a[3] = k;
				for(int l = k + 1;l <= 12;++l)
				{
					a[4] = l;
					for(int g = l + 1;g <= 12;++g)
					{
						a[5] = g;
						 if(check())
						 ans++;
					}
				}
			}
		}
	}
	printf("%d\n",ans);
	return 0;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章