题解:补♂课第110场

overview
【强迫症系列】所有代码的main函数都只由for语句构成,其余部分也尽可能地用for语句缩短代码。

A - 算术运算

#include<stdio.h>
long long a,b;
int main()
{
    for(char c; scanf("%lld %c %lld",&a,&c,&b)!=EOF; printf("%lld\n",c=='+'?a+b:a-b));
}

B - 判断数字个数

输入有空格,要用gets整行读入。

#include<stdio.h>
int cnt[256]= {0};
int main()
{
    for(char s[1024]; gets(s);)
    {
        for(int i=0; s[i]; ++i)
            ++cnt[s[i]];
        for(char i='0'; i<='9'; cnt[i++]=0)
            if(cnt[i])
                printf("%c:%d\n",i,cnt[i]);
    }
}

如果嫌这组题字符串太多,也可以像这样用getchar避开字符串操作。

#include<stdio.h>
int cnt[256]= {0};
int main()
{
    for(char ch; (ch=getchar())!=EOF; ++cnt[ch])
        if(ch=='\n')
            for(char i='0'; i<='9'; cnt[i++]=0)
                if(cnt[i])
                    printf("%c:%d\n",i,cnt[i]);
}

C - 素数回文数的个数

#include<stdio.h>
int isPrime(int n)
{
    for(int i=2; i*i<=n; ++i)
        if(n%i==0)
            return 0;
    return 1;
}
int isPalindromic(int n)
{
    int m=0;
    for(int t=n; t; t/=10)
        m=m*10+t%10;
    return m==n;
}
int main()
{
    for(int n,ans; scanf("%d",&n)!=EOF; printf("%d\n",ans))
        for(int i=11+(ans=0); i<=n; ++i)
            if(isPrime(i)&&isPalindromic(i))
                ++ans;
}

优解:手动构造回文数判断是否为素数。考虑有多次询问,可以先生成一张回文素数表,对于每次询问直接查表。此外,下述代码中表恰好是从小到大存储的,因此可以直接二分查找第一个比n小的数的下标作为答案,请自己实现。

#include<stdio.h>
int len=0,a[128]= {0};
int isPrime(int n)
{
    for(int i=2; i*i<=n; ++i)
        if(n%i==0)
            return 0;
    return 1;
}
int main()
{
    for(int i=11; i<=99; i+=11)
        if(isPrime(i))
            a[len++]=i;
    for(int i=1; i<=9; ++i)
        for(int j=0; j<=90; j+=10)
            if(isPrime(i*101+j))
                a[len++]=i*101+j;
    for(int n,ans; scanf("%d",&n)!=EOF; printf("%d\n",ans))
        for(int i=ans=0; i!=len; ++i)
            if(n>=a[i])
                ++ans;
}

D - 扩号匹配

#include<stdio.h>
char s[1024];
int pipei(int p)
{
    for(int cnt=1; cnt;)
    {
        if(s[--p]=='2')++cnt;
        else --cnt;
    }
    return p;
}
int main()
{
    for(int n; scanf("%d%s",&n,s)!=EOF; printf("\n"))
        for(int i=0; i!=n; ++i)
            if(s[i]=='2')
                printf("%d ",pipei(i)+1);
}

E - 加减乘除

#include<stdio.h>
int a,b;
int main()
{
    for(char c; scanf("%d %c",&a,&c)!=EOF;)
    {
        if(c=='!')
        {
            for(int i=b=1; i<=a; b*=i++);
            printf("%d\n",b);
            continue;
        }
        scanf("%d",&b);
        if(!b&&(c=='/'||c=='%'))
            printf("error\n");
        else
            printf("%d\n",
                   c=='+'?a+b:
                   c=='-'?a-b:
                   c=='*'?a*b:
                   c=='/'?a/b:a%b);
    }
}

F - 期末考试第二题——比较数字个数

#include<stdio.h>
int main()
{
    for(char flag,s[2][128],cnt[256]; gets(s[0]),gets(s[1]); printf("%d\n",!flag))
    {
        for(int i=flag=0; i!=256; cnt[i++]=0);
        for(int i=0; s[1][i]; ++i)
            ++cnt[s[1][i]];
        for(int i=0; s[0][i]; ++i)
            if('a'<=s[0][i]&&s[0][i]<='z')
                if(--cnt[s[0][i]]<0)
                    flag=1;
    }
}

G - 期末考试第三题——最大最小数之差

#include<stdio.h>
long long p,q,len,a[32];
int main()
{
    for(char s[32]; gets(s); printf("%lld\n",q-p))
    {
        for(int i=p=q=len=0; s[i]; ++i)
        {
            if('0'<=s[i]&&s[i]<='9')
                a[len++]=s[i]-'0';
            if('a'<=s[i]&&s[i]<='f')
                a[len++]=s[i]-'a'+10;
            if('A'<=s[i]&&s[i]<='F')
                a[len++]=s[i]-'A'+10;
            for(int j=0,t; j!=len; ++j)//使插入元素有序
                if(a[j]>a[len-1])
                {
                    t=a[j];
                    a[j]=a[len-1];
                    a[len-1]=t;
                }
        }
        for(int i=0; i!=len; ++i)
            p=p*16+a[i];
        for(int i=len-1; i!=-1; --i)
            q=q*16+a[i];
    }
}

H - 停车场收费

#include<stdio.h>
int main()
{
    for(double t; scanf("%lf",&t)!=EOF; printf("%.2lf\n",t<3?5:t>20.5?40:2*t-1));
}

I - Inserting Something in Strings

#include<stdio.h>
int main()
{
    for(char pos,s[2][16]; scanf("%s%s",s[0],s[1])!=EOF; printf("\n"))
    {
        for(int i=pos=0; s[0][i]; ++i)
            if(s[0][pos]<s[0][i])
                pos=i;
        for(int i=0; s[0][i]; ++i)
            printf("%c%s",s[0][i],i==pos?s[1]:"");
    }
}

J - 有未知数的表达式

递归求表达式的应用,熟悉栈结构也可以用之代替。
留下思考:如果表达式中有括号怎么处理。

#include<stdio.h>
#include<string.h>
#include<math.h>
char s[32];
int work(int l,int r)
{
    for(int i=r; i>=l; --i)
    {
        if(s[i]=='+')
            return work(l,i-1)+work(i+1,r);
        if(s[i]=='-')
            return work(l,i-1)-work(i+1,r);
    }
    for(int i=l,b=0; i<=r; ++i)
    {
        if('0'>s[i]||s[i]>'9')
        {
            if(i==l)break;
            return b*work(i,r);
        }
        b=b*10+s[i]-'0';
        if(i==r)return b;
    }
    for(int i=r; i>=l; --i)
        if(s[i]=='^')
            return pow(work(l,i-1),work(i+1,r));
    return l>r?0:3;
}
int main()
{
    for(; scanf("%s",s)!=EOF; printf("%d\n",work(0,strlen(s)-1)));
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值