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。
时间限制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);
}
}