set.cpp/c/pas

set.cpp/c/pas
時間限制1s,內存限制256MB。

題目描述


據說大主任認識一個自認爲很聰明的人。
有一天,大主任問那個人:
“你能告訴我一個集合的表示法嗎?”
“當然,我這麼聰明!”他回答說,“那是一組在兩個大括號包圍的元素,但括號裏也可以爲空,這些元素可以是一個新的集合,也可以是一個字母,他們之間用','隔開。”
“那麼,”大主任說,“如果我給你一個表示,你能告訴我它是一個正確的集合嗎?”
“當然,我這麼聰明!”他又回答說,“傻瓜都會做!”
“很好,”大主任想,“這樣我就可以證明他是傻瓜了!”
現在大主任準備用這樣一道題來虐掉那個人。你將得到下列規定:
集合:{元素列表}
元素列表:空 or 元素子列表
元素子列表:元素 or 元素 , 元素子列表
元素:子元素 or 集合
子元素:{ or , or }
注意:“空”,表示沒有任何成分,並不是有一個表示“空”的字符。
大主任覺得這題太水了,他不屑於寫標程,倒是給出了一大堆邪惡的數據。爲了幫助大主任證明那個人是傻瓜,作爲大主任下手的你也就難逃幫他寫標程的厄運了。
請你寫一個程序判斷一個表達式是否滿足上述規定的集合。


輸入描述


本題有多組數據。
輸入的第一行爲數據組數T。
第2行到第T+1行,每行給出一個字符串。

輸出描述

共T行。
按下列格式輸出:
若是一個滿足規定的集合,則輸出:Word #數據組編號: Set
若不是,則輸出: Word #數據組編號: No Set

輸入樣例


4
{}
{{}}
{{}},{,}}
{,,}

輸出樣例


Word #1: Set
Word #2: Set
Word #3: Set
Word #4: No Set

提示


如果你覺得題面太糾結了,那麼請看第三個樣例,它爲什麼是合法的。
{ {}} , {,} }

數據範圍及約定


對於20%的數據,|S|<=10。

對於100%的數據,T<=10,|S|<=100。



寫完拍完那個噁心的mm數據結構根本沒有時間了。。。

什麼速度...算了不說了。

這個題。。題面太糾結”是極佳的概述啊!

當然我也是語死早,

其實他是一個區間DP啊!

最暴力可以記錄f[5][L][R],分別表示一段區間能否構成題面上告訴的哪些什麼怪物東西。

再想一下發現可以只用記錄能不能集合和集合列表。

當然其實只用F[L][R],因爲集合和集合列表也是沒有區別的啊。

最後只用判斷C[1]和C[n]是不是‘{’ ‘}’,在判斷F[2][n-1]能否構成一個集合或集合列表。

然後。。就木有然後了。

O(n^3)


區間DP先枚舉區間長度當然無可厚非(就像本沙茶的代碼)。

不過diamondlx吊方法:

從右向左枚舉L,再從左向右枚舉R,這樣就能構成一個拓撲序列。~~~

其實我以前也發現這種順序太渣。。但是也沒有什麼更好的方法,

今天領教了。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define rep(i,l,r) for (int i=l;i<=r;++i)
const int MAX_N=105;
bool f[MAX_N][MAX_N];
char c[MAX_N];
bool check(){
	int n=strlen(c+1);
	if (n==2){
		if(c[1]=='{'&&c[2]=='}') return true;
			else return false;
		}
	rep(i,1,n) f[i][i]=1;
	rep(i,1,n-1)
		if (c[i]=='{'&&c[i+1]=='}') f[i][i+1]=1;
	rep(i,3,n)
		rep(l,1,n-i+1){
			int r=l+i-1;
			if (c[l]=='{'&&c[r]=='}') f[l][r]|=f[l+1][r-1];
			rep(k,l+1,r-1){
				if (c[k]==',') f[l][r]|=f[l][k-1]&f[k+1][r];
				}
			}
	//rep(l,1,n) rep(r,l,n)
	//	printf("%d %d %d\n",l,r,f[l][r]);
	if (c[1]=='{'&&c[n]=='}') return f[2][n-1];
	return false;
}
int main(){
	freopen("set.in","r",stdin);
	freopen("set.out","w",stdout);
	int T;scanf("%d",&T);
	rep(i,1,T){
		scanf("%s",c+1);
		memset(f,0,sizeof f);
		if (check()) printf("Word #%d: Set\n",i);
			else	 printf("Word #%d: No Set\n",i);
		}
}


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