【ZOJ 3480】Duck Typing

题意

1.有t组数据,输入时每组数据之间空格隔开,输出时也要求空格隔开。

2.每组都是一行begin开始,一行end结束。

3.class ClassName[:Super] 表示声明一个类型,Super值存在时,说明它继承Super类型。

4.def ClassName.Method 表示声明ClassName类型的一个方法。

5.undef ClassName.Method 表示删除该类型下该方法。

6.call ClassName.Method 表示调用该方法,如果该类型本身没有该方法,就去看它祖先是否有。

分析

可以用字符串string的函数处理,也可以用char处理(我写的姿势不是很好看,手动捂脸)。

说几个容易错的地方:。。其实姿势不同,会错的地方也不同。最口怕的是我WA在了把“oops"拼写成"opps"了QAQ。还有比如”.“不要写成”:“了!

代码

char处理

#include<cstdio>
#include<cstring>

struct cla
{
    char name[50];
    int mnum;//num of method
    char md[50][50];//method
    int super;
} a[10050];
void read(char c,int &flag,char name[][50])
{
    int k=0;
    int len=0;
    int cnt=0;
    flag=1;
    if (c==‘b‘ ||c==‘e‘) flag=0;//begin/end
    while((c=getchar())&&c!=‘\n‘)
    {
        cnt++;
        if (cnt==1 && flag)
        {
            if (c==‘e‘) flag=2;
            else if (c==‘a‘) flag=3;
            else if (c==‘n‘) flag=4;
        }
        if (flag==1 && cnt>5 ||//class ClassName
                flag==2 && cnt>3 ||//def ClassName.Method
                flag==3 && cnt>4 ||//undef ClassName.Method
                flag==4 && cnt>5 ||//call ClassName.Method
                flag==5 )//class Sub:Super
        {
            name[k][len]=c;
            if (c==‘:‘)
            {
                name[k][len]=‘\0‘;
                len=-1;
                k=1;
                flag=5;
            }
            if (c==‘.‘)
            {
                name[k][len]=‘\0‘;
                len=-1;
                k=1;
            }
            len++;
        }
    }
}

int check(int flag,int &mp,int &fp,char name[][50],int cnum)
{
    int defined1=0,defined2=0;
    int i,j;

    for(i=1; i<=cnum; i++)
        if (strcmp(a[i].name,name[0])==0)
            defined1= i;
    if (flag==1)
    {
        if(defined1) return -1;
        return 0;
    }
    if (flag==5)
    {
        if(defined1) return -1;
        else
        {
            for(i=1; i<=cnum; i++)
                if(strcmp(a[i].name,name[1])==0)
                    defined1= i;
            if (defined1==0) return -1;
            return defined1;
        }
    }
    if (!defined1) return -1;

    int f=defined1,ok=0;
    while(f!=0&&!ok)
    {
        for(j=1; j<=a[f].mnum; j++)
        {
            if (strcmp(a[f].md[j],name[1])==0)
            {
                defined2=j;
                ok=1;
            }
        }
        mp=defined2;
        fp=f;
        if(flag==3)f=a[f].super;
        else f=0;
    }

    if (flag==2)
    {
        if (defined2) return -2;
    }
    else if (!defined2) return -1;
    return defined1;
}

void work(int flag,int p,int mp,int fp,char name[][50],int &cnum)
{
    if(flag==1)
    {
        cnum++;
        strcpy(a[cnum].name,name[0]);
        a[cnum].super=0;
        printf("class %s\n",name[0]);
    }
    else if(flag==2)
    {
        if(p==-2)
        {
            printf("redef %s.%s\n",name[0],name[1]);
        }
        else
        {
            strcpy(a[p].md[++a[p].mnum],name[1]);
            printf("def %s.%s\n",a[p].name,name[1]);
        }
    }
    else if(flag==3)
    {
        printf("invoke %s.%s\n",a[fp].name,name[1]);
    }
    else if(flag==4)
    {
        memset(a[fp].md[mp],0,sizeof(a[fp].md[mp]));
        printf("undef %s.%s\n",name[0],name[1]);
    }
    else if(flag==5)
    {
        cnum++;
        strcpy(a[cnum].name,name[0]);
        a[cnum].super=p;
        printf("class %s:%s\n",name[0],name[1]);
    }
}
int main()
{
    int t;
    scanf("%d ",&t);
    while(t--)
    {
        int cnum=0;
        int flag;

        //mp 是该方法在该类型的方法里是第几个
        //fp 是该方法的所属的类型是第几个
        int mp,fp;
        char c;
        memset(a,0,sizeof(a));
        while(~(c=getchar())&&c!=‘\n‘)
        {
            char name[2][50]= {"",""};
            read(c,flag,name);
            if(flag)
            {
                int p=check(flag,mp,fp,name,cnum);
                if(p==-1)
                    printf("oops!\n");
                else
                    work(flag,p,mp,fp,name,cnum);
            }
        }
        printf("\n");
    }
    return 0;
}

string处理

#include <iostream>
#include <cstdio>
#include <map>
#include <string>

using namespace std;

int main()
{
    map<string,string>fa;
    map<string,int>cla;
    map<string,int>me;
    string s,first,cName,m,cm,super;
    int t;
    cin>>t;
    while (t)
    {
        cin>>s;
        if (s=="begin")
        {
            cla.clear();
            fa.clear();
            me.clear();
        }
        else if (s=="end")
        {
            t--;
            cout<<"\n";
        }
        else if (s=="class")
        {
            cin>>first;
            int i=first.find(‘:‘);
            if (i==string::npos)
            {
                if (cla[first])
                    cout<<"oops!\n";
                else
                {
                    cla[first]=1;
                    cout<<s<<" "<<first<<"\n";
                }
            }
            else
            {
                super=first.substr(i+1);
                first=first.erase(i);
                if (cla[super]==1 && cla[first]==0)
                {
                    cla[first]=1;
                    fa[first]=super;
                    cout<<s<<" "<<first<<":"<<super<<"\n";
                }
                else
                    cout<<"oops!\n";
            }
        }
        else if (s=="def")
        {
            cin>>first;
            cName=first.substr(0,first.find(‘.‘));//sub str before .
            if (cla[cName]==0)
                cout<<"oops!\n";
            else
            {
                if (me[first]==1)
                    cout<<"redef "<<first<<"\n";
                else
                {
                    me[first]=1;
                    cout<<s<<" "<<first<<"\n";
                }
            }
        }
        else if (s=="undef")
        {
            cin>>first;
            if (me[first]==0)
                cout<<"oops!\n";
            else
            {
                me[first]=0;
                cout<<s<<" "<<first<<"\n";
            }
        }
        else if (s=="call")
        {
            cin>>first;
            m=first.substr(first.find(‘.‘));
            cName=first.substr(0,first.find(‘.‘));
            cm=first;
            while(me[cm]==0 && (!cName.empty()))
            {
                cm=fa[cName]+m;
                cName=fa[cName];
            }
            if (cName.empty())
                cout<<"oops!\n";
            else
                cout<<"invoke "<<cm<<"\n";
        }
    }
    return 0;
}
时间: 2024-10-25 19:41:43

【ZOJ 3480】Duck Typing的相关文章

【ZOJ 4070】Function and Function

[链接] 我是链接,点我呀:) [题意] [题解] 递归一会. 会发现最后肯定是0,1一直循环. 开始循环之后就直接返回结果就好. [代码] #include <bits/stdc++.h> #define ll long long #define rep1(i,a,b) for (int i = a;i <= b;i++) #define rep2(i,a,b) for (int i = a;i >= b;i--) using namespace std; const int N

【ZOJ 1221】Risk

题 题意 给你20个城市的相邻关系,求给定任意两个城市的最短距离 分析 求任意两个城市最短距离,就是用floyd算法,我脑残忘记了k是写在最外层的. 代码 #include<stdio.h> #include<algorithm> #define N 22 using namespace std; int n,x,a,b,test,d[N][N],from,to; void read() { for(int j=1; j<=x; j++) { scanf("%d&q

【ZOJ 5689】Deque and Balls(普通dp)

题意:给出一个序列,按照顺序一个一个放入双端队列(可以放在头部也可以放在尾部),一个队列的美丽指数就是数列中a[i]>a[i+1]的个数,求美丽指数的期望*2^n的值. 解题思路:方便起见,我们将a[i]>a[i+1]的情况称为D情况. 由题意可以知道最后得到的序列一共有2^(n-1)个,设ans=所有序列中D情况个数的总和,最后就是求sum/2^(n-1)*2^n = 2*sum 对于将要插入的a[j],sum=原先的D情况总和*2+a[j]产生的D情况-(a[i]=a[j])的情况 如果a

【ZOJ 2974】Just Pour the Water(矩阵快速幂)

传送门:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2974 题意 给出n个杯子与初始水量同时进行操作 将其中的水同时平均分入所指定的杯子 进行x次后 输出杯子剩余水量 刚拿到这个题,第一反应是递推找规律,但是因为每个杯子的初始水量是未知的,所以能找的只是每个杯子水量与其余杯子水量的关系. 但是看到了操作次数巨大,而且最多只有20个杯子,感觉可以用快速幂去做. 我们假设矩阵a[i][j]代表第i个杯子的水有a[i][j

【ZOJ 3844】Easy Task

题意 每次把序列中最大的数a的一个和最小的数b的一个变成a-b.求最后是否能使序列里的数全部相同,能则输出这个相同的数. 分析 一定是有解的,证明想不出来. 可以直接暴力模拟. 代码 #include<cstdio> int ok(int a[],int n) { int i; for(i=1; i<n; i++) if(a[i]!=a[i+1])break; return i==n; } int main() { int t; scanf("%d",&t);

【ZOJ 3897】Candy canes//Fiddlesticks

题 题意 给你一串数,a1...an,从左到右每次让一个数减小c,如果这个数小于c,那就减为0.第n个数减小后,又从第一个开始从左到右.如果这次某个数减小到0,那就改变方向,如果遇到已经是0的,就跳过.且总共最多减少n+5次,求最后变为0的数是第几个. 分析 Input 1 8 80200 100 100 100 100 80 160 200 Output 3 样例分析: 最多可以减少8+5=13次,于是最后减为0的就是第三个数了: 200 100 100 100 100 80 160 200

【ZOJ 3856】Goldbach(FFT)

题意:最多使用三个质数做加法和乘法,问得到X有多少种方案. 这道题的话分几种情况讨论清楚就好了. 1.只有一个数的情况,如果这个数是质数则方案数加1 2.有两个数的情况,可以将两个数做加法和乘法,加法的话将质数得到的数字做一遍FFT,乘法直接做sqrt(n) * sqrt(n)就好了 3.有三个数的情况,分别有三种方法,分别是a + b + c, a + b * c,a * b * c 对于a * b * c,暴力遍历一遍就好,对于a + b * c,首先暴力遍历下b * c,然后再将一个数的两

【ZOJ】3380 Patchouli&#39;s Spell Cards

http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3957 题意:m个位置,每个位置填1~n的数,求至少有L个位置的数一样的概率(1<=n,m,l<=100) #include <cstdio> #include <cstring> #include <algorithm> using namespace std; struct inum { static const int N=205,

【ZOJ】3785 What day is that day? ——浅谈KMP应用之ACM竞赛中的暴力打表找规律

首先声明一下,这里的规律指的是循环,即找到最小循环周期.这么一说大家心里肯定有数了吧,“不就是next数组性质的应用嘛”. 先来看一道题 ZOJ 3785 What day is that day? Time Limit: 2 Seconds      Memory Limit: 65536 KB It's Saturday today, what day is it after 11 + 22 + 33 + ... + NN days? Input There are multiple tes