3.30(PTA)

目录

7-1 重要的话说三遍

7-2 两小时学完C语言

7-3 拯救外星人

7-4 谁能进图书馆

7-5 试试手气

7-6 查验身份证

7-7 连续因子

7-8 出租

7-10 列车厢调度


7-1 重要的话说三遍

这道题就是直接输出三次题目给出的字符串就行。

#include<stdio.h>
int main()
{
    printf("I'm gonna WIN!\nI'm gonna WIN!\nI'm gonna WIN!\n");
    return 0;
}

7-2 两小时学完C语言

这道题就是直接读入然后运算输出就行。

#include<stdio.h>
int main()
{
    int n, k, m;
    scanf("%d%d%d", &n, &k, &m);
    printf("%d", n-(k*m));
    return 0;
}

7-3 拯救外星人

这道题我用的是前缀和求阶乘的方法,感觉这个方法用来求阶乘确实是否方便快捷加轻松简单。

7-4 谁能进图书馆

这道题就是根据题目的一个模拟。

其有以下几种情况:

1.两人都大于或等于禁入年龄线,此时两人都可进入;

2.两人都小于禁入年龄线,此时两人都不可进入;

3.其中一个大于或等于陪同年龄线,另一个小于禁入年龄线,此时两人都可进入,但要注意谁是大于或等于的人,谁是小于的人;

4.其中一个大于或等于禁入年龄线但小于陪同年龄线,另一个小于禁入年龄线,此时前者可以进入,但后者不能进入;

然后分别根据这四种情况进行对应输出即可。

#include<stdio.h>
#include<algorithm>
using namespace std;
int main()
{
    int a, b, c, d;
    int c1=1;
    int d2=2;
    scanf("%d%d%d%d", &a, &b, &c, &d);
    if(c>=a&&d>=a)
    {
        printf("%d-Y %d-Y\nhuan ying ru guan", c, d);
        return 0;
    }
    if(c<a&&d<a)
    {
        printf("%d-N %d-N\nzhang da zai lai ba", c, d);
        return 0;
    }
    int minx, maxx;
    minx=min(c, d);
    maxx=max(c, d);
    if(maxx>=b&&minx<a)
    {
        if(c>d)
            printf("%d-Y %d-Y\nqing %d zhao gu hao %d", c, d,c1, d2);
        else
            printf("%d-Y %d-Y\nqing %d zhao gu hao %d", c, d, d2, c1);
        return 0;
    }
    if(maxx>=a&&maxx<b&&minx<a)
    {
        if(c>d)
            printf("%d-Y %d-N\n%d: huan ying ru guan", c, d, c1);
        else
            printf("%d-N %d-Y\n%d: huan ying ru guan", c, d, d2);
        return 0;
    }
}

7-5 试试手气

这道题我一开始的想法是这样的:开一个二维的行和列都是6的数组,并为其赋从6到0递减的值,然后先把题目给出的那6个数所对应的数组中的位置改为0;

然后进行k-1次循环,每次循环就把每行的最大值(第一个非0的值)赋值为0;

第k次循环所取的每行的第一个非0的值即为所求答案。

#include<stdio.h>
int main()
{
    int a[6][6]={
        {6, 5, 4, 3, 2, 1},
        {6, 5, 4, 3, 2, 1},
        {6, 5, 4, 3, 2, 1},
        {6, 5, 4, 3, 2, 1},
        {6, 5, 4, 3, 2, 1},
        {6, 5, 4, 3, 2, 1}
    };
    int n[6];
    for(int i=0;i<6;i++)
    {
        scanf("%d", &n[i]);
    }
    for(int i=0;i<6;i++)
    {
        for(int j=0;j<6;j++)
        {
            if(a[i][j]==n[i])
            {
                a[i][j]=0;
                break;
            }
        }
    }
    int k;
    scanf("%d", &k);
    for(int i=0;i<k-1;i++)
    {
        for(int o=0;o<6;o++)
        {
            for(int p=0;p<6;p++)
            {
                if(a[o][p]!=0)
                {
                    a[o][p]=0;
                    break;
                }
            }
        }
    }
    for(int o=0;o<6;o++)
        {
            for(int p=0;p<6;p++)
            {
                if(o==5)
                {
                    if(a[o][p]!=0)
                    {
                        printf("%d\n", a[o][p]);
                        return 0;
                    }
                }
                if(a[o][p]!=0)
                {
                    printf("%d ", a[o][p]);
                    break;
                }
            }
        }
}

其实后面两部,那两次循环是没有必要的,合并为一个循环即可,其中用ai[]数组来记录每次循环后所对应的最大值组合。代码如下:

#include<stdio.h>
int main()
{
    int a[6][6]={
        {6, 5, 4, 3, 2, 1},
        {6, 5, 4, 3, 2, 1},
        {6, 5, 4, 3, 2, 1},
        {6, 5, 4, 3, 2, 1},
        {6, 5, 4, 3, 2, 1},
        {6, 5, 4, 3, 2, 1}
    };
    int n[6];
    for(int i=0;i<6;i++)
    {
        scanf("%d", &n[i]);
    }
    for(int i=0;i<6;i++)
    {
        for(int j=0;j<6;j++)
        {
            if(a[i][j]==n[i])
            {
                a[i][j]=0;
                break;
            }
        }
    }
    int k;
    scanf("%d", &k);
    int ai[6];
    for(int i=0;i<k;i++)
    {
        for(int o=0;o<6;o++)
        {
            for(int p=0;p<6;p++)
            {
                if(a[o][p]!=0)
                {
                    ai[o]=a[o][p];
                    a[o][p]=0;
                    break;
                }
            }
        }
    }
    for(int i=0;i<6;i++)
    {
        if(i==5)
        {
            printf("%d\n", ai[i]);
            return 0;
        }
        printf("%d ", ai[i]);
    }
}

7-6 查验身份证

这道题一开始就是直接跟着题目写的,虽然过了,但代码非常的冗长。其实可以用打表的方式来优化一下代码,两段代码我都附在下面。

优化前代码:

#include<stdio.h>
int main()
{
    int n;
    scanf("%d", &n);
    int k=0;
    for(int i=0;i<n;i++)
    {
        char a[20];
        scanf("%s", a);
        long long s;
        s=(a[0]-'0')*7+
            (a[1]-'0')*9+
            (a[2]-'0')*10+
            (a[3]-'0')*5+
            (a[4]-'0')*8+
            (a[5]-'0')*4+
            (a[6]-'0')*2+
            (a[7]-'0')*1+
            (a[8]-'0')*6+
            (a[9]-'0')*3+
            (a[10]-'0')*7+
            (a[11]-'0')*9+
            (a[12]-'0')*10+
            (a[13]-'0')*5+
            (a[14]-'0')*8+
            (a[15]-'0')*4+
            (a[16]-'0')*2;
        s=s%11;
        if(s==0)
        {
            if(a[17]!='1')
            {
                k=1;
                printf("%s\n", a);
                continue;
            }
            continue;
        }
        if(s==1)
        {
            if(a[17]!='0')
            {
                k=1;
                printf("%s\n", a);
                continue;
            }
            continue;
        }
        if(s==2)
        {
            if(a[17]!='X')
            {
                k=1;
                printf("%s\n", a);
                continue;
            }
            continue;
        }
        if(s==3)
        {
            if(a[17]!='9')
            {
                k=1;
                printf("%s\n", a);
                continue;
            }
            continue;
        }
        if(s==4)
        {
            if(a[17]!='8')
            {
                k=1;
                printf("%s\n", a);
                continue;
            }
            continue;
        }
        if(s==5)
        {
            if(a[17]!='7')
            {
                k=1;
                printf("%s\n", a);
                continue;
            }
            continue;
        }
        if(s==6)
        {
            if(a[17]!='6')
            {
                k=1;
                printf("%s\n", a);
                continue;
            }
            continue;
        }
        if(s==7)
        {
            if(a[17]!='5')
            {
                k=1;
                printf("%s\n", a);
                continue;
            }
            continue;
        }

        if(s==8)
        {
            if(a[17]!='4')
            {
                k=1;
                printf("%s\n", a);
                continue;
            }
            continue;
        }
        if(s==9)
        {
            if(a[17]!='3')
            {
                k=1;
                printf("%s\n", a);
                continue;
            }
            continue;
        }
        if(s==10)
        {
            if(a[17]!='2')
            {
                k=1;
                printf("%s\n", a);
                continue;
            }
            continue;
        }
    }
    if(k==0)
        printf("All passed");
    return 0;
}

优化后代码:

#include<stdio.h>
char v[11]={'1','0','X','9','8','7','6','5','4','3','2'};
int main()
{
    int n;
    scanf("%d", &n);
    int k=0;
    for(int i=0;i<n;i++)
    {
        char a[20];
        scanf("%s", a);
        long long s;
        s=(a[0]-'0')*7+
            (a[1]-'0')*9+
            (a[2]-'0')*10+
            (a[3]-'0')*5+
            (a[4]-'0')*8+
            (a[5]-'0')*4+
            (a[6]-'0')*2+
            (a[7]-'0')*1+
            (a[8]-'0')*6+
            (a[9]-'0')*3+
            (a[10]-'0')*7+
            (a[11]-'0')*9+
            (a[12]-'0')*10+
            (a[13]-'0')*5+
            (a[14]-'0')*8+
            (a[15]-'0')*4+
            (a[16]-'0')*2;
        s=s%11;
        if(v[s]!=a[17])
        {
            k=1;
                printf("%s\n", a);
                continue;
        }
    }
    if(k==0)
        printf("All passed");
    return 0;
}

7-7 连续因子

这道题有两种思路,分别如下:

思路1:求出n的所有的因子,然后去找其中的最长的连续因子

#include<stdio.h>
#include<math.h>
int main()
{
    long long n;
    scanf("%lld", &n);
    if(n==2)
    {
        printf("1\n2\n");
        return 0;
    }
    int c=0;
    for(int i=2;i<=(int)sqrt(n);i++)
    {
        if(n%i==0)
            c=1;
    }
    if(c==0)
    {
        printf("1\n%lld\n", n);
        return 0;
    }
    int xi=0;
    int l=0;
    long long s;
    for(int i=2;i<=(int)sqrt(n);i++)
    {
        s=1;
        for(int j=i;s*j<=n;j++)
        {
            s=s*j;
            if(n%s==0&&j-i+1>l)
            {
                xi=i;
                l=j-i+1;
            }
        }
    }
    printf("%d\n", l);
    for(int i=xi;i<xi+l;i++)
    {
        if(i==xi+l-1)
        {
            printf("%d\n", i);
            return 0;
        }
        printf("%d", i);
        printf("*");
    }
}

思路2:去找一个x,这个x是有几个连续的因子相乘得到的因子,只要这个x能被n整除,说明这个x是n的因子,找到组成x的最多的连续因子的个数。

由于13的阶乘以及大于了2的31次方,所以,组成x的连续个因子的个数最多为12个,又因为要求最长的连续因子个数,所以选择从12开始向1遍历。

#include<bits/stdc++.h>
int main()
{
    long n;
    scanf("%ld", &n);
    long s;
    for(int i=12;i>=1;i--)
    {
        for(int j=2;j<=(int)sqrt(n);j++)
        {
            s=1;
            for(int k=0;k<i;k++)
            {
                s=s*(j+k);
            } 
            if(s>n)
                break;
            if(n%s==0){
                printf("%d\n", i);
                for(int p=0;p<i;p++)
                {
                    if(p==i-1)
                    {
                        printf("%d\n", j+i-1);
                        return 0;
                    }
                    printf("%d*", j+p);
                }
                
            }
           
        }
    }
    printf("1\n%ld", n);
    return 0;
}

7-8 出租

这道题的关键在与声明的两数组的对应关系。

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
int main()
{
    char c[20];
    scanf("%s", c);
    int a[20];
    int arr[10];
    int index[12];
    int l=strlen(c);
    for(int i=0;i<l;i++)
    {
        a[i]=c[i]-'0';
    }
    int arri=0;
    for(int i=0;i<l;)
    {
        if(i==0)
        {
            arr[arri]=a[i];
            arri++;
        }
        else
        {
            for(int j=0;j<arri;j++)
            {
                if(a[i]==arr[j])
                    goto tiao;
            }
            arr[arri]=a[i];
            arri++;
        }
        tiao:
        i++;
    }
    sort(arr, arr+arri, greater<int>());
    int indexi=0;
    for(int i=0;i<l;i++)
    {
        for(int j=0;j<arri;j++)
        {
            if(a[i]==arr[j])
            {
                index[indexi]=j;
                indexi++;
            }
        }
    }
    printf("int[] arr = new int[]{");
    for(int i=0;i<arri;i++)
    {
        if(i==arri-1)
        {
            printf("%d", arr[i]);
            break;
        }
        printf("%d,", arr[i]);
    }
    printf("};\nint[] index = new int[]{");
    for(int i=0;i<indexi;i++)
    {
        if(i==indexi-1)
        {
            printf("%d", index[i]);
            break;
        }
        printf("%d,", index[i]);
    }
    printf("};\n");
    return 0;
}

7-10 列车厢调度

这道题我的思路是先看3轨道中有无元素,有则判断最后一个元素是否与2轨道中当前元素相同,相同则3轨道的长度减一,2轨道的当前元素后移一位,然后continue,若不是,则进行下面操作;

判断1轨道中的当前元素是否与2轨道的当前元素相同,是则两轨道的当前元素后移一位,否则1轨道的当前元素复制到3轨道中,3轨道长度加一,然后后移一位。

这里我选择用字符数组来表示轨道。

#include<stdio.h>
#include<string.h>
int cixu[1000000];
int xi=0;
int main()
{
    char a[30];
    char b[30];
    scanf("%s", a);
    scanf("%s", b);
    //printf("%s\n", a);
    //printf("%s\n", b);
    char c[30];
    int ci=0;
    int l=strlen(a);
    int j=0;
    for(int i=0;i<l;)
        {
            int f=0;
            if(ci!=0)
            {
                int xci=ci;
                for(int o=0;o<xci;o++)
                {
                    if(c[xci-1-o]==b[i])
                    {
                        cixu[xi]=3;//printf("3->2\n");
                        xi++;
                        i++;
                        f=1;
                        ci--;
                        //printf("1 %d %d %d\n", xi, ci, xci);
                        continue;
                    }
                    else
                        break;
                }
            }
        if(j<l)
        {
            f++;
            if(a[j]==b[i])
            {
                cixu[xi]=1;//printf("1->2\n");
                xi++;
                i++;
                j++;
                continue;
            }
            else
            {
                cixu[xi]=2;//printf("1->3\n");
                xi++;
                c[ci]=a[j];
                ci++;
                j++;
            }
        }
            
            if(f==0)
            {
                printf("Are you kidding me?");
                return 0;
            }
        }
    
    for(int i=0;i<xi;i++)
    {
        if(cixu[i]==1)
        {
            printf("1->2\n");
        }
        if(cixu[i]==2)
        {
            printf("1->3\n");
        }
        if(cixu[i]==3)
        {
            printf("3->2\n");
        }
    }
    return 0;
}
  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值