第三次上机赛标程

  渣诚解题报告在此,果然每次解题报告写得都比我认真多了Orz……那我就扔个标程随便写写好了……

  A. 新·神魔之井

  陈题,角谷猜想。不多说。

#include<cstdio>
using namespace std;
int main()
{
    int n,ans;
    while(~scanf("%d",&n))
    {
        for(ans=0; n>1; ++ans)
            n=(n&1)?n*3+1:n/2;
        printf("%d\n",ans);
    }
}

  B. AString.h(III)

  其实就是HDU1274变了个题目描述,这道题没办法随机数据,数据编得直恶心……递归随便搞搞即可。非递归不好写但我也写了一份。

#include<cstdio>
#include<cstring>
#include<cctype>
using namespace std;
char str[105];
int len;
int translate(int pos)
{
    for(; pos<len&&str[pos]!=')'; ++pos)
    {
        int num=0,tmp=-1;
        for(; isdigit(str[pos]); ++pos)
            num=num*10+str[pos]-'0';
        if(num==0)
            ++num;
        while(num--)
            if(str[pos]=='(')
                tmp=translate(pos+1);
            else
                printf("%c",str[pos]);
        if(tmp!=-1)
            pos=tmp;
    }
    return pos;
}
int main()
{
    while(~scanf("%s",str))
    {
        len=strlen(str);
        translate(0);
        putchar('\n');
    }
}
#include<iostream>
#include<string>
#include<cctype>
#include<stack>
using namespace std;
stack<pair<string,int> > s;
int main()
{
    string str;
    while(cin>>str)
    {
        string ans="";
        for(int i=0; i<str.size(); ++i)
        {
            if(str[i]==')')
            {
                pair<string,int> top=s.top();
                s.pop();
                string tmp=ans;
                while(--top.second)
                    ans+=tmp;
                ans=top.first+ans;
                continue;
            }
            int num=0;
            for(; isdigit(str[i]); ++i)
                num=num*10+str[i]-'0';
            if(num==0)
                ++num;
            if(str[i]=='(')
            {
                s.push(make_pair(ans,num));
                ans="";
                continue;
            }
            while(num--)
                ans+=str[i];
        }
        while(!s.empty())
        {
            pair<string,int> top=s.top();
            s.pop();
            string tmp=ans;
            while(--top.second)
                ans+=tmp;
            ans=top.first+ans;
        }
        cout<<ans<<endl;
    }
}

  C. AString.h(IV)

  是出了两年的上机原题原数据,每次都只改了题目描述罢了……通配符是唬人的,以通配符为分割,一段段分别KMP就好。

#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=10005;
char str[MAXN],s[MAXN];
int next[MAXN],sl,tl;
void getnext(int p,int l)
{
    int j=0,k=-1;
    next[0]=-1;
    while(p+j<l)
    {
        while(k>-1&&s[p+j]!=s[p+k])
            k=next[k];
        ++j;
        ++k;
        next[j]=(s[p+j]==s[p+k])?next[k]:k;
    }
}
int kmp(int pos,int p,int l)
{
    int i=0,j=0;
    getnext(p,l);
    while(pos+i<sl)
    {
        while(j>-1&&str[pos+i]!=s[p+j])
            j=next[j];
        ++i;
        if(++j==l)
            return i;
    }
    return -1;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%s",s);
        getchar();
        gets(str);
        sl=strlen(str);
        tl=strlen(s);
        bool flag=true;
        int pos=0,p=0;
        while(flag&&p<tl)
        {
            int q=p;
            while(q<tl&&s[q]!='*')
                ++q;
            pos=kmp(pos,p,q-p);
            p=q+1;
            if(pos==-1)
                flag=false;
        }
        puts(flag?"Yes":"No");
    }
}

  D. 京东牌奶茶

  最基本的迷宫,求最短步数,所以bfs一遍即可。

#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int dx[]= {-1,0,1,0},dy[]= {0,1,0,-1};
char g[15][15];
int sx,sy;
struct point
{
    int x,y,cnt;
    point(int _x=0,int _y=0,int _cnt=0):x(_x),y(_y),cnt(_cnt) {}
};
int bfs()
{
    queue<point> q;
    q.push(point(sx,sy,0));
    while(!q.empty())
    {
        point tmp=q.front();
        q.pop();
        for(int i=0; i<4; ++i)
        {
            int tx=tmp.x+dx[i],ty=tmp.y+dy[i];
            if(g[tx][ty]=='Z')
                return tmp.cnt+1;
            else if(g[tx][ty]=='*')
            {
                q.push(point(tx,ty,tmp.cnt+1));
                g[tx][ty]='#';
            }
        }
    }
    return 0;
}
int main()
{
    int n,m;
    while(~scanf("%d%d",&n,&m))
    {
        memset(g,'#',sizeof(g));
        for(int i=1; i<=n; ++i)
            for(int j=1; j<=m; ++j)
            {
                scanf(" %c",&g[i][j]);
                if(g[i][j]=='L')
                {
                    sx=i;
                    sy=j;
                }
            }
        int ans=bfs();
        ans>0?printf("%d\n",ans):puts("WHERE?!");
    }
}

  E. Thor的收费站

  一开始只是想考查大家的递归,没想到会有人直接用Catalan数来搞。所以放两段代码吧。

#include<cstdio>
using namespace std;
int dfs(int p,int q)
{
    if(q==0)
        return 1;
    if(p<q)
        return 0;
    return dfs(p-1,q)+dfs(p,q-1);
}
int main()
{
    int n;
    while(~scanf("%d",&n))
        printf("%d\n",dfs(n,n));
}
#include<cstdio>
using namespace std;
const int MAXN=18;
int Catalan[MAXN];
int main()
{
    Catalan[0]=0;
    Catalan[1]=1;
    for(int i=2; i<MAXN; ++i)
        Catalan[i]=Catalan[i-1]*(4*i-2)/(i+1);
    int n;
    while(~scanf("%d",&n))
        printf("%d\n",Catalan[n]);
}

  F. You-know-what

  陈题,当年错误的题目描述不知道坑了多少人。

#include<iostream>
#include<string>
using namespace std;
int main()
{
    ios::sync_with_stdio(false);
    string str,op,tmp;
    int n,x,y;
    while(cin>>str>>n)
    {
        while(n--)
        {
            cin>>op;
            switch(op[0])
            {
            case 'I':
                cin>>x>>tmp;
                str.insert(x,tmp);
                break;
            case 'D':
                cin>>x>>y;
                str.erase(x,y);
                break;
            case 'C':
                str+=str;
                break;
            }
        }
        cout<<str<<endl;
    }
}

  G. repeat repeat repeat

  源自POJ2406,考查对KMP中next数组的理解。不过暴力搞也能过,后缀数组也能搞……但是没必要。

#include<cstdio>
#include<cstring>
using namespace std;
const int MAXN=1000005;
char str[MAXN];
int next[MAXN];
int main()
{
    while(~scanf("%s",str)&&str[0]!='.')
    {
        int i=-1,j=0,len=strlen(str);
        next[0]=-1;
        while(j<len)
            if(i==-1||str[j]==str[i])
                next[++j]=++i;
            else
                i=next[i];
        printf("%d\n",(len%(j-i)==0)?len/(j-i):1);
    }
}

  基本上就这些了,对我来说没啥特别有趣的题目。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值