第三次练习赛解题报告及标程

来源:互联网 发布:淘宝的集市店 编辑:程序博客网 时间:2024/06/05 22:35

  渣诚拖了好久的解题报告,于是我还是自行解决吧……

  A. Arthur的收藏夹
  B. Chem is A Brand New Try!
  E. RPS GAMES

  三道上机原题,没啥讲的,见上机题解。

  C. 链表的中间节点

  陈题,题干里Hint的提示足够简洁明了,唯一要注意的是分割字符串的方法,下面的标程给出了两种方式(手动分割,以及strtok函数);还有,其实没必要把字符转化成数字。

#include<cstdio>#include<cstdlib>#include<cstring>using namespace std;struct LinkList{    char data[5];    LinkList *next;};char str[1005];void CreateList(LinkList *&L){    LinkList *s,*r;    L=(LinkList *)malloc(sizeof(LinkList));    r=L;    int f=0,l=strlen(str);    for(int i=0; i<l; ++i)        if(str[i+1]==' '||i==l-1)        {            ++i;            s=(LinkList *)malloc(sizeof(LinkList));            for(int j=0; j<i-f; j++)                s->data[j]=str[j+f];            s->data[i-f]='\0';            r->next=s;            r=s;            f=i+1;        }    r->next=NULL;}void MiddleOfList(LinkList *&L){    LinkList *p1=L->next,*p2=L->next;    while(p2->next!=NULL)    {        p2=p2->next->next;        p1=p1->next;    }    printf("%s\n",p1->data);}void DestroyList(LinkList *&L){    LinkList *pre=L,*p=L->next;    while(p)    {        free(pre);        pre=p;        p=pre->next;    }    free(pre);}int main(){    int t;    scanf("%d",&t);    getchar();    while(t--)    {        gets(str);        LinkList *L;        CreateList(L);        MiddleOfList(L);        DestroyList(L);    }}
#include<cstdio>#include<cstring>#include<string>#include<list>using namespace std;char str[1005];list<string> data;list<string>::iterator it,mid;int main(){    int t;    scanf("%d",&t);    getchar();    while(t--)    {        gets(str);        char *sub=strtok(str," ");        while(sub)        {            data.push_back(sub);            sub=strtok(NULL," ");        }        it=data.begin();        mid=it++;        while(it!=data.end())        {            advance(it,2);            ++mid;        }        printf("%s\n",(*mid).c_str());        data.clear();    }}

  D. Who Should I Accompany?(Ⅱ)

  双向约瑟夫,加点条件罢了,双链表纯模拟。

#include<cstdio>#include<cstdlib>using namespace std;struct DLinkList{    int data;    DLinkList *prior,*next;};void CreateList(DLinkList *&L,int n){    DLinkList *s,*r;    L=(DLinkList *)malloc(sizeof(DLinkList));    r=L;    for(int i=1; i<=n; ++i)    {        s=(DLinkList *)malloc(sizeof(DLinkList));        s->data=i;        r->next=s;        s->prior=r;        r=s;    }    r->next=L->next;    L->next->prior=r;}void Josephus(DLinkList *&L,int k){    DLinkList *p=L->next->prior,*q;    int cnt=0;    while(p->next!=p)    {        if(cnt&1)        {            for(int i=1; i<k+cnt; ++i)                p=p->prior;            q=p->prior;            p->prior=q->prior;            q->prior->next=p;            p=p->prior;        }        else        {            for(int i=1; i<k+cnt; ++i)                p=p->next;            q=p->next;            p->next=q->next;            q->next->prior=p;            p=p->next;        }        free(q);        ++cnt;    }    printf("%d\n",p->data);    free(p);    free(L);}int main(){    int n,k;    while(~scanf("%d%d",&n,&k))    {        DLinkList *L;        CreateList(L,n);        Josephus(L,k);    }}
#include<cstdio>#include<list>using namespace std;list<int> data;list<int>::iterator p,q;int main(){    int n,k;    while(~scanf("%d%d",&n,&k))    {        for(int i=1; i<=n; ++i)            data.push_back(i);        p=data.begin();        int cnt=0;        while(cnt!=n-1)        {            if(cnt&1)            {                for(int i=1; i<k+cnt; ++i)                {                    if(p==data.begin())                        p=data.end();                    --p;                }                q=p++;                if(p==data.end())                    p=data.begin();            }            else            {                for(int i=1; i<k+cnt; ++i)                {                    ++p;                    if(p==data.end())                        p=data.begin();                }                q=p;                if(p==data.begin())                    p=data.end();                --p;            }            data.erase(q);            ++cnt;        }        printf("%d\n",*p);        data.clear();    }}

  F. 大富翁

  这道题不太好搞,边界处理有点恶心。双链表不用说了,我的做法是先往一边数B+C次,然后再往回数C次,这样可以回避一部分边界情况。

#include<cstdio>#include<cstdlib>using namespace std;struct DLinkList{    int data;    DLinkList *prior,*next;};void CreateList(DLinkList *&L,int n){    DLinkList *s,*r;    L=(DLinkList *)malloc(sizeof(DLinkList));    r=L;    for(int i=1; i<=n; i++)    {        s=(DLinkList *)malloc(sizeof(DLinkList));        s->data=i;        r->next=s;        s->prior=r;        r=s;    }    r->next=NULL;}void DestroyList(DLinkList *&L){    DLinkList *pre=L,*p=L->next;    while(p!=NULL)    {        free(pre);        pre=p;        p=pre->next;    }    free(pre);}int main(){    int t,n,m;    scanf("%d",&t);    while(t--)    {        DLinkList *L,*p,*q;        scanf("%d%d",&n,&m);        CreateList(L,n);        p=L->next;        while(m--)        {            int a,b,c;            scanf("%d",&a);            if(a!=0)            {                scanf("%d%d",&b,&c);                if(a==1)                {                    for(int i=0; i<b+c; ++i)                    {                        if(p->next==NULL)                            break;                        p=p->next;                    }                    for(int i=0; i<c; ++i)                    {                        if(p==L)                        {                            p=p->next;                            break;                        }                        p->prior->next=p->next;                        if(p->next!=NULL)                            p->next->prior=p->prior;                        q=p;                        p=p->prior;                        free(q);                    }                }                else if(a==-1)                {                    for(int i=0; i<b+c; ++i)                    {                        if(p->prior==L)                            break;                        p=p->prior;                    }                    for(int i=0; i<c; ++i)                    {                        if(p==NULL)                        {                            p=L;                            while(p->next!=NULL)                                p=p->next;                            break;                        }                        p->prior->next=p->next;                        if(p->next!=NULL)                            p->next->prior=p->prior;                        q=p;                        p=p->next;                        free(q);                    }                }            }        }        p=L->next;        while(p!=NULL)        {            printf("%d ",p->data);            p=p->next;        }        putchar('\n');        DestroyList(L);    }}
#include<cstdio>#include<list>using namespace std;list<int> data;list<int>::iterator p,q;int main(){    int t,n,m;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        for(int i=0; i<=n; ++i)            data.push_back(i);        p=data.begin();        ++p;        while(m--)        {            int a,b,c;            scanf("%d",&a);            if(a==0)                continue;            scanf("%d%d",&b,&c);            switch(a)            {            case 1:                for(int i=0; i<b+c; ++i)                {                    ++p;                    if(p==data.end())                    {                        --p;                        break;                    }                }                for(int i=0; i<c; ++i)                {                    if(p==data.begin())                    {                        ++p;                        break;                    }                    q=p;                    --p;                    data.erase(q);                }                break;            case -1:                for(int i=0; i<b+c; ++i)                {                    --p;                    if(p==data.begin())                    {                        ++p;                        break;                    }                }                for(int i=0; i<c; ++i)                {                    if(p==data.end())                    {                        --p;                        break;                    }                    q=p;                    ++p;                    data.erase(q);                }                break;            }        }        for(p=data.begin(),++p; p!=data.end(); ++p)            printf("%d ",*p);        putchar('\n');        data.clear();    }}

  G. Thor's Play

  栈的纯模拟,无坑点,不说了。

#include<cstdio>using namespace std;const int MAXN=10005;int stack[MAXN],size;int main(){    int n,m,k;    char str[10];    while(~scanf("%d%d",&n,&m))    {        size=0;        while(m--)        {            scanf("%s",str);            bool flag=true;            switch(str[0])            {            case 'P':                scanf("%d",&k);                if(size==n)                    flag=false;                else                    stack[++size]=k;                break;            case 'R':                if(size==0)                    flag=false;                else                    --size;                break;            case 'G':                scanf("%d",&k);                while(size>0&&stack[size]!=k)                    --size;                if(size==0)                    flag=false;                else                    --size;                break;            }            puts(flag?"SUCCEED":"ERROR");        }        for(int i=size; i>=1; --i)            printf("%d ",stack[i]);        putchar('\n');    }}
#include<cstdio>#include<stack>using namespace std;stack<int> s;int main(){    int n,m,k;    char str[10];    while(~scanf("%d%d",&n,&m))    {        while(m--)        {            scanf("%s",str);            bool flag=true;            switch(str[0])            {            case 'P':                scanf("%d",&k);                if(s.size()==n)                    flag=false;                else                    s.push(k);                break;            case 'R':                if(s.empty())                    flag=false;                else                    s.pop();                break;            case 'G':                scanf("%d",&k);                while(!s.empty()&&s.top()!=k)                    s.pop();                if(s.empty())                    flag=false;                else                    s.pop();                break;            }            puts(flag?"SUCCEED":"ERROR");        }        while(!s.empty())        {            printf("%d ",s.top());            s.pop();        }        putchar('\n');    }}

  H. 优雅的XML

  SZM大神出的题,我在13年成都现场赛上做过一道很相似的题(HDU4782),当时没搞出来。主要是要考虑到一切情况,边界条件众多,小心使得万里船。我的代码很难看。

#include<cstdio>using namespace std;int main(){    int len=0,cnt=0;    char buf[4096];    while((buf[len]=getchar())!=EOF)        ++len;    for(int i=0; i<len; ++i)    {        if(buf[i]==' '||buf[i]=='\n'||buf[i]=='\t')            continue;        if(buf[i]=='<')        {            int j=i+1;            while(buf[j]==' '||buf[j]=='\n'||buf[j]=='\t')                ++j;            if(buf[j]=='/')                --cnt;            for(int k=0; k<cnt; ++k)                putchar('\t');            if(buf[j]!='/')                ++cnt;            putchar(buf[i++]);            int quo=0;            while(buf[i]==' '||buf[i]=='\n'||buf[i]=='\t')                ++i;            if(buf[i]=='/')            {                putchar(buf[i++]);                while(buf[i]==' '||buf[i]=='\n'||buf[i]=='\t')                    ++i;            }            while(buf[i]!='>'&&buf[i]!=' '&&buf[i]!='\n'&&buf[i]!='\t')                putchar(buf[i++]);            while(buf[i]==' '||buf[i]=='\n'||buf[i]=='\t')                ++i;            if(buf[i]!='>')            {                putchar(' ');                for(; buf[i]!='>'; ++i)                {                    if(!(quo&1)&&(buf[i]==' '||buf[i]=='\n'||buf[i]=='\t'))                        continue;                    putchar(buf[i]);                    if(buf[i]=='\"'&&buf[i-1]!='\\')                    {                        ++quo;                        if(!(quo&1))                        {                            ++i;                            while(buf[i]==' '||buf[i]=='\n'||buf[i]=='\t')                                ++i;                            if(buf[i]=='>')                                break;                            --i;                            putchar(' ');                        }                    }                }            }            putchar(buf[i]);            j=i-1;            while(buf[j]==' '||buf[j]=='\n'||buf[j]=='\t')                --j;            if(buf[j]=='/')                --cnt;            putchar('\n');        }    }}

  送一组数据,能过这一组应该就没问题了。输入为:

< html xmlns="http://www.w3school.com.cn">< head >< link href="/static/css/oj3rd.css"  rel = "stylesheet" type="text/css" / >< / head > < body > < div id  =  "header  " class="clearfix" ><a href= "/problem/group/85/create/" ></a>< / div ></body></ html>

  输出效果为:

<html xmlns="http://www.w3school.com.cn"><head><link href="/static/css/oj3rd.css" rel="stylesheet" type="text/css" /></head><body><div id="header  " class="clearfix"><a href="/problem/group/85/create/"></a></div></body></html>

  解题报告真的不好写也懒得写……看看标程应该也能懂的吧。

0 0