2015 湘潭大学程序设计比赛(Internet)

前段时间,由于校园网的问题,一直打不开csdn,再加上前阵子的懈怠,我已经很久没写博客了,不过,为了即将到来的省赛和蓝

桥杯,我决定要改过自新,奋发向上。

题目链接:http://202.197.224.59/OnlineJudge2/index.php/Contest/problems/contest_id/38

1.仙剑奇侠传

题目链接:
http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1225

水题,不解释。

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int i,n,l,ans=0,x,tmp=100;
        scanf("%d%d",&n,&l);
        for(i=0;i<n;i++)
        {
            scanf("%d",&x);
            if(l>=x)
                ans+=10/(l-x+1);
            if(ans>=tmp)
            {
                tmp+=100;
                l++;
            }
        }
        printf("%d %d\n",l,ans);
    }
    return 0;
}


2.折叠

题目链接:

http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1226

水题,不解释。

#include<iostream>
#include<string>
#include<cstdio>
using namespace std;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        int i,l,a=0,b=0;
        string str;
        cin>>str;
        l=str.size();
        if(l==1)
            cout<<str<<endl;
        else if(l%2==0)
        {
            for(i=0;i<l/2;i++)
                a=a*10+str[i]-'0';
            for(i=l-1;i>=l/2;i--)
                b=b*10+str[i]-'0';
            printf("%d\n",a+b);
        }
        else
        {
            for(i=0;i<=l/2;i++)
                a=a*10+str[i]-'0';
            for(i=l-1;i>l/2;i--)
                b=b*10+str[i]-'0';
            printf("%d\n",a+b*10);
        }
    }
    return 0;
}

3.Digit

题目链接:

http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1227

当时比赛时,语言理解能力太差了,不知道数码是什么意思,后来经队友解释,才知道是123456789101112...这些数一直排列下

去,然后让你求第n个数,我顿时,就哭晕了。其实要解这题也不是很难,首先模拟位数,找出是哪个位数,然后求解便可。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;

typedef long long ll;

int main()
{
    int T,t=9;;
    ll i,num[10],maxn[10];
    num[1]=9;
    maxn[1]=1;
    for(i=2;i<10;i++)
    {
        t*=10;
        num[i]=i*t+num[i-1];
        maxn[i]=maxn[i-1]*10;
    }
    scanf("%d",&T);
    while(T--)
    {
        ll n;
        scanf("%lld",&n);
        if(n<10)
        {
            printf("%lld\n",n);
            continue;
        }
        ll pos=1;
        for(i=1;i<10;i++)
            if(num[i]>=n)
            {
                pos=i;
                n-=num[i-1];
                break;
            }
        int flag=0;
        if(n%pos==0)
            flag=-1;
        long long ans=maxn[pos]+n/pos+flag;
        for(i=0;i<pos;i++)
        {
            if((pos-i)%pos==n%pos)
            {
                printf("%lld\n",ans%10);
                break;
            }
            ans/=10;
        }
    }
    return 0;
}

4.最小的数

题目链接:

http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1228

以前做过类似的题,不过没说只能相邻的交换。不过这题也不是很难。首先另开一个数组,从小到大排列,然后从首位依次遍历(首位不能为0)与较小数交换,为什么不说最小数呢,因为题目给了交换步数限制,所以你在有限步数内找到较小数然后交换,如果步数还有充裕的,则进行下一位操作,操作过程重复第一步即可。

#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        char str[1010],tmp[1010];
        int vis[1010];
        int i,j,k,l,p,t1;
        memset(vis,0,sizeof(vis));
        scanf("%s%d",str,&k);
        l=strlen(str);
        strcpy(tmp,str);
        sort(tmp,tmp+l);
        for(i=0;i<l&&k;i++)
        {
            for(j=0;j<l;j++)
            {
                int flag=1;
                if(vis[j]||tmp[j]>=str[i])
                    continue;
                if(!i&&tmp[j]=='0')
                    continue;
                for(p=i+1;p<l;p++)
                {
                    if(str[p]==tmp[j])
                    {
                        if(k<p-i)
                            flag=0;
                        else
                        {
                            k-=(p-i);
                            for(t1=p;t1>i;t1--)
                                swap(str[t1],str[t1-1]);
                            vis[j]=1;
                        }
                        break;
                    }
                }
                if(flag)
                    break;
            }
            //cout<<str<<endl;
            //cout<<k<<endl;
        }
        printf("%s\n",str);
    }
    return 0;
}

5.烦人的异或

5.说实话,我还不知道这题怎么做呢。先贴上别人的博客,以后再更新。

http://www.cnblogs.com/zhengguiping--9876/p/4461329.html

6.Curious Maze

6.很蛋疼的一道题,这几天忙着省赛,以后更新。

http://202.197.224.59/OnlineJudge2/index.php/Contest/read_problem/cid/38/pid/1230

7.人生成就

题目链接:
http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1231

dp水题。先用dp找出最大数,然后再模拟刚才的过程求出所有的路。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;

int a[510][510];
int dp[510][510];
int num[510][510];

int main()
{
    int n;
    while(scanf("%d",&n)!=EOF)
    {
        int i,j;
        memset(dp,0,sizeof(dp));
        memset(num,0,sizeof(num));
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                scanf("%d",&a[i][j]);
                dp[i][j]=max(dp[i][j-1],dp[i-1][j])+a[i][j];
            }
        }
        num[1][1]=1;
        for(i=1;i<=n;i++)
        {
            for(j=1;j<=n;j++)
            {
                if(a[i][j]==dp[i][j]-dp[i][j-1])
                    num[i][j]+=num[i][j-1];
                if(a[i][j]==dp[i][j]-dp[i-1][j])
                    num[i][j]+=num[i-1][j];
                num[i][j]%=123456;
            }
        }
        printf("%d\n",num[n][n]);
    }
    return 0;
}

8.括号匹配

题目链接:
http://202.197.224.59/OnlineJudge2/index.php/Problem/read/id/1232

stack的一个简单运用,思想,我代码里的备注已经很详细了就不多说了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<stack>
#include<map>
#include<algorithm>
using namespace std;

struct node
{
    int index,x,y,r[4];//index表示它的序号,x表示它的属性,y表示它的后序或前序,r[]依次代表小括号,中括号,大括号
}no[100010];

int main()
{
    char str[100010];
    int mm,x;
    map<char,int> m;
    stack<node> s;
    m['(']=1;m['[']=2;m['{']=3;
    m[')']=4;m[']']=5;m['}']=6;//用map存放括号的属性
    while(scanf("%s",str+1)!=EOF)
    {
        memset(no,0,sizeof(no));
        int i;
        for(i=1;str[i];i++)
        {
            no[i].index=i;
            no[i].x=m[str[i]];
            if(m[str[i]]<=3)
                s.push(no[i]);
            else
            {
                node p,t;
                p=s.top();
                s.pop();
                no[i].y=p.index;    //记录它的前序
                p.y=i;
                if(s.size())
                {
                    t=s.top();
                    s.pop();
                    t.r[1]+=p.r[1];
                    t.r[2]+=p.r[2];
                    t.r[3]+=p.r[3];
                    t.r[p.x]++;
                    s.push(t);
                }
                no[p.index]=p;  //赋值前序
            }
        }
        scanf("%d",&mm);
        while(mm--)
        {
            scanf("%d",&x);
            int j;
            j=min(x,no[x].y);   //因为给出的x有可能是后序,所以要判断
            printf("%d %d %d %d\n",no[x].y,no[j].r[1],no[j].r[2],no[j].r[3]);
        }
        printf("\n");
    }
    return 0;
}




你可能感兴趣的:(2015,湘潭大学程序设计比赛Inter)