B - Vasya and Types CodeForces - 87B (模拟)

B. Vasya and Types
time limit per test
2 seconds
memory limit per test
256 megabytes
input
standard input
output
standard output

Programmer Vasya is studying a new programming language &K*. The &K* language resembles the languages of the C family in its syntax. However, it is more powerful, which is why the rules of the actual C-like languages are unapplicable to it. To fully understand the statement, please read the language's description below carefully and follow it and not the similar rules in real programming languages.

There is a very powerful system of pointers on &K* — you can add an asterisk to the right of the existing type X — that will result in new type X * . That is called pointer-definition operation. Also, there is the operation that does the opposite — to any type of X, which is a pointer, you can add an ampersand — that will result in a type &X, to which refers X. That is called a dereference operation.

The &K* language has only two basic data types — void and errtype. Also, the language has operators typedef and typeof.

  • The operator "typedef A B" defines a new data type B, which is equivalent to AA can have asterisks and ampersands, and Bcannot have them. For example, the operator typedef void** ptptvoid will create a new type ptptvoid, that can be used as void**.
  • The operator "typeof A" returns type of A, brought to void, that is, returns the type void**...*, equivalent to it with the necessary number of asterisks (the number can possibly be zero). That is, having defined the ptptvoid type, as shown above, the typeof ptptvoid operator will return void**.

An attempt of dereferencing of the void type will lead to an error: to a special data type errtype. For errtype the following equation holds true: errtype* = &errtype = errtype. An attempt to use the data type that hasn't been defined before that will also lead to the errtype.

Using typedef, we can define one type several times. Of all the definitions only the last one is valid. However, all the types that have been defined earlier using this type do not change.

Let us also note that the dereference operation has the lower priority that the pointer operation, in other words &T *  is always equal to T.

Note, that the operators are executed consecutively one by one. If we have two operators "typedef &void a" and "typedef a* b", then at first a becomes errtype, and after that b becomes errtype* = errtype, but not &void* = void (see sample 2).

Vasya does not yet fully understand this powerful technology, that's why he asked you to help him. Write a program that analyzes these operators.

Input

The first line contains an integer n (1 ≤ n ≤ 100) — the number of operators. Then follow n lines with operators. Each operator is of one of two types: either "typedef A B", or "typeof A". In the first case the B type differs from void and errtype types, and besides, doesn't have any asterisks and ampersands.

All the data type names are non-empty lines of no more than 20 lowercase Latin letters. The number of asterisks and ampersands separately in one type in any operator does not exceed 10, however if we bring some types to void with several asterisks, their number may exceed 10.

Output

For every typeof operator print on the single line the answer to that operator — the type that the given operator returned.

Examples
input
Copy
5
typedef void* ptv
typeof ptv
typedef &&ptv node
typeof node
typeof &ptv
output
Copy
void*
errtype
void
input
Copy
17
typedef void* b
typedef b* c
typeof b
typeof c
typedef &b b
typeof b
typeof c
typedef &&b* c
typeof c
typedef &b* c
typeof c
typedef &void b
typeof b
typedef b******* c
typeof c
typedef &&b* c
typeof c
output
Copy
void*
void**
void
void**
errtype
void
errtype
errtype
errtype
Note

Let's look at the second sample.

After the first two queries typedef the b type is equivalent to void*, and с — to void**.

The next query typedef redefines b — it is now equal to &b = &void* = void. At that, the с type doesn't change.

After that the с type is defined as &&b* = &&void* = &void = errtype. It doesn't influence the b type, that's why the next typedef defines c as &void* = void.

Then the b type is again redefined as &void = errtype.

Please note that the c type in the next query is defined exactly as errtype******* = errtype, and not &void******* = void******. The same happens in the last typedef.


这种又臭又长的题干真是看着就恶心。。。比赛的时候到比赛结束都没弄明白题意。。。

有两种操作:

1、typedef + ss + 变量名(ss中可含&和*,除去&和*    ①若ss为void,则定义一个变量,值为void。若*数量小于&,则变量值为errtype,且之后只要用这个变量名定义的变量都为errtype。否则多几个*  值就为void+多几个*。②若ss为未定义的变量名,则此变量值为errtype。无论有多少个&和*。③若ss已经定义,则新定义的变量值为ss的值加上*多于&的数量。如果加上后*的数量变为负 则新变量的值变为errtype。)

2、typeof + ss (ss中可含&和*,除去&和*  ①若ss未定义则输出errtype 。②若ss值中包含*的数量加上输入的ss中*的数量-&的数量小于0,那么就输出errtype。 ③否则输出ss的值,然后输入的ss中*的数量-&的数量是多少就多输出几个*。 

如果还不懂的话就看代码吧。。。

注意:

1、void类型刚开始就存在 初始化mp["void"]=1;表示变量名为void的值为void+(1-1)个*

2、这样mp[ss]值为0表示ss未定义,为1表示为void,大于1就表示void+(值-1)个*,小于0就是errtype。

#include <bits/stdc++.h>
#define ll long long
#define inf 0x3f3f3f3f
using namespace std;
const int maxn=500010;
const long long mod=1e9+7;
int n,m,q,k,flag,x,f,y,p;
int ans,tmp,cnt;
int a[maxn],c[maxn];
char s[maxn],ss[maxn],sss[maxn];
map<string,int>mp;
string str1,str2;
int main()
{
    //ios::sync_with_stdio(false);
    int T;
    while(scanf("%d",&n)!=EOF)
    {
        mp.clear();
        mp["void"]=1;
        for(int i=0;i<n;i++)
        {
            scanf("%s",s);
            if(strcmp(s,"typedef")==0)
            {
                scanf("%s %s",ss,sss);
                int l=strlen(ss);
                int i=0;
                int ans=0,cnt=0;
                str1="";
                for(int i=0;i<l;i++)
                {
                    if(ss[i]=='&') ans--;
                    else if(ss[i]=='*') ans++;
                    else str1+=ss[i];
                }
                cnt=mp[str1];
                if(cnt>0) cnt+=ans;
                else cnt=0;
                mp[(string)sss]=cnt;
            }
            else
            {
                scanf("%s",ss);
                int l=strlen(ss);
                int i=0;
                int ans=0,cnt=0;
                str1="";
                for(int i=0;i<l;i++)
                {
                    if(ss[i]=='&') ans--;
                    else if(ss[i]=='*') ans++;
                    else str1+=ss[i];
                }
                cnt=mp[str1];
                if(cnt>0) cnt+=ans;
                else cnt=0;
                if(cnt<=0) puts("errtype");
                else
                {
                    printf("void");
                    for(int i=1;i<cnt;i++)
                    printf("*");
                    puts("");
                }
            }
        }
    }
    return 0;
}

再吐槽一遍,这题真恶心,对于英语不好的我来说简直是天书,只能看样例猜题意,还猜不对。

猜你喜欢

转载自blog.csdn.net/lsd20164388/article/details/80272482