PKU演習問メモ(8/30)
PKU落ちてて更新できない……
No. | 問題名 | 問題の種類および解法 | 難易度 |
---|---|---|---|
2269 | Friends | 構文解析・集合演算 | ★★★☆☆ |
2269 Friends
問題概要
{ABC} {ABC}+{DEFG}+{Z}+{} {ABE}*{ABCD} {ABCD}-{CZ} {ABC}+{CDE}*{CEZ} ({ABC}+{CDE})*{CEZ}
のような集合の式が与えられる。これらを計算せよ。
ただし
- +
- 集合の結びを表す
- *
- 集合の交わりを表す
- -
- 集合差を表す
また、演算子は左結合で、優先順位は'*'>'+' = '-'の順とする。
ソースコード
char str[300]; int eval(int s,int t) { int p=t-1,q,d=0; for(;p>=s;p--)//項をみる { if(str[p]=='(')d++; if(str[p]==')')d--; if(d==0&&(str[p]=='+'||str[p]=='-'))break; } if(p>=s)//項が複数 { int l=eval(s,p),r=eval(p+1,t); if(str[p]=='+')return l|r; return l&~r; } for(p=t-1;p>=s;p--)//因数をみる { if(str[p]=='(')d++; if(str[p]==')')d--; if(d==0&&str[p]=='*')break; } if(p>=s)//因数が複数 { int l=eval(s,p),r=eval(p+1,t); return l&r; } if(str[s]=='(')return eval(s+1,t-1); int ret=0; for(p=s;p<t;p++)if('A'<=str[p]&&str[p]<='Z')ret|=1<<str[p]-'A'; return ret; } int main() { while(gets(str)) { int a=eval(0,strlen(str)); putchar('{'); rep(i,26)if(1<<i&a)putchar('A'+i); putchar('}'); puts(""); } return 0; }