pat 乙级 1031~1040

文章目录

1031
1032
1033
1034
1035
1036
1037
1038
1039
1040


1031

解题思路:

1.定义一个函数isTrue判断字符串是否满足题意
2.对于全部满足输出"All passed"和不满足时输出字符串,可以使用flag
3.对于isTrue函数中通过for循环如果有不是数字的字符返回false,并且求出加权和sum
4.对于末尾数组中有x对应数组中10,设置一个临时变量tem,如果s[17]==‘x’,将tem=10,然后在判断是否与检验数组中的值对应

参考代码:

#include<iostream>
using namespace std;
/*
    解题思路:
    1.定义一个函数isTrue判断字符串是否满足题意
    2.对于全部满足输出"All passed"和不满足时输出字符串,可以使用flag
    3.对于isTrue函数中通过for循环如果有不是数字的字符返回false,并且求出加权和sum
    4.对于末尾数组中有x对应数组中10,设置一个临时变量tem,如果s[17]=='x',将tem=10,然后在判断是否与
    检验数组中的值对应
*/


bool isTrue(string s)
{
    int a[17]={7,9,10,5,8,4,2,1,6,3,7,9,10,5,8,4,2};
    int b[11]={1,0,10,9,8,7,6,5,4,3,2};
    int sum=0;
    for(int i=0; i<17; i++)
    {
        if(s[i]<'0' || s[i]>'9')
           return false;
        sum+=(s[i]-'0')*a[i];
    }
    int temp=(s[17]=='X')?10:(s[17]-'0');
    return b[sum%11]==temp;           //如果最后一位检验相同,就返回True;否则返回false;也可以用if-else来写

}
int main()
{
    int n,flag=0;
    string s;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        cin >> s;
        if(!isTrue(s))
        {
            flag=1;
            cout << s << endl;
        }
    }
    if(flag==0)
        cout << "All passed";
    return 0;
}

1032

解题思路:

1.将成绩放到学校编号对应的下标数组中,数组表示成绩之和

2.将max表示最大成绩的下标,由于题中,学校编号是从1开始,所以max初值为1,最后直接输出max1,和a[max1]。

参考代码:

#include<iostream>
using namespace std;
/*
    解题思路:
    1.学校编号school,成绩和数组a[]={0},
    2.
*/
int main()
{
    int n,tem,max1=1,school;
    cin >> n;
    int a[n+1]={0};
    for(int i=0; i<n; i++)
    {
        cin >> school >> tem;
        a[school]+=tem;
    }
    for(int i=2; i<=n; i++)
    {
        if(a[i]>a[max1])
            max1=i;
    }
    cout << max1 << " " << a[max1];
    return 0;
}

注意事项:

1.定义数组a的长度时是n+1并且初值为0,因为题中含义是n个学生,所以学校的编号最大是n,查找最大值时的那个循环要能遍历到n,如果定义数组a的长度为n,那么最后成绩之和最大的是a[n](未赋初值的数组元素值是任意数),而最大值下标是n。
2.假设max1=1,也就是假设第一个学校的总分最大


1033

解题思路:

坏掉的键保存在字符串bad中,应该输⼊的⽂字保存在should中,遍历整个应该输⼊的字符串,
因为坏键以⼤写给出,所以如果在bad⾥⾯找到了should[i]的⼤写,表示这个字符对应的键坏了,则跳
过这个字符不输出,continue跳过~如果should[i]是⼤写并且在bad中找到了’+’,表示上档键坏了,⼤
写⽆法输出,所以这个字符也不能输出,continue跳过~如果都没跳过,则要输出should[i]

参考代码:

#include <iostream>
#include <cctype>
using namespace std;
int main() {
 string bad, should;
 getline(cin, bad);
 getline(cin, should);
 for (int i = 0, length = should.length(); i < length; i++) {
 if (bad.find(toupper(should[i])) != string::npos) continue;
 if (isupper(should[i]) && bad.find('+') != string::npos) continue;
 cout << should[i];
 }
 return 0; }

1034

解题思路:

1.三个函数:gcd求出最大公约数;func对分数进行化简,main输入a b c d
2.gcd用辗转相除求最大约数,
      if(t20)
      return t1;
      else
      gcd(t2,t1%t2);
3.gcd函数
      1.如果m*n
0,分为2种情况:分母为0或分母为0,输出时加上判断分子是否为0
      2.用flag表示异号为1,同号为0
      3.对m,n都取绝对值,并向除

4.func函数:
      1.解决Inf与分子为0的问题
      2.定义flag,对m,n取整,x分子与分母的商
      3.解决对于分数可能添加(-的问题
      4.不论分子与分母是整除还是不整除,都先要输出x
      5.如果对于整除的情况,根据flag看输不输出),并最后退出此函数
      6.如果对于不是整除的情况,就要加上一个空格,以便让假分数的整数部分与分数分开
      7.输出真分数的问题
            1.先计算假分数去除整数部分的分子
            2.然后调用gcd函数算出此时分母与分子的最大公约数
            3.然后算出最简形式
            4.按照分数的格式输出,注意最后还要根据flag看输出输出)。
      5.main:
            1.输入四个值a b c d
            2.对于加法:通分手动算出分子分母然后将其作为参数代入func函数中求最简形式
            3.对于减法,类似只是相减
            4.对于乘法,类似根据手动的策略
            5.对于除法,类似手动求倒数然后代入

参考代码:

#include <iostream>
#include <cmath>
#include<cstdio>
using namespace std;
long long a, b, c, d;       //为啥要是long long类型?答:必须范围足够大
/*

*/


//辗转相除求最大约数
long long gcd(long long t1, long long t2) {
   if(t2==0)
    return t1;
  else
    gcd(t2,t1%t2);
}

//对分数进行化简
void func(long long m, long long n)
{
 if (m * n == 0)
 {
     printf("%s", n==0?"Inf":"0");
     return ;
 }

 //异号是1,同号0
 bool flag=((m<0 && n>0) || (m>0 && n<0));
 m=abs(m); n= abs(n);
 long long x = m/n;

 printf("%s", flag?"(-":"");

 if (x!=0)
    printf("%lld",x);    //注意这里的格式化输出格式是小写的LLL 不是 11111111

 if (m%n==0)
 {
        printf("%s",flag?")":"");
    return ;
 }

 if (x!=0)
    printf(" ");
 m=m-x*n;
 long long t = gcd(m,n);
 m=m/t; n=n/t;
 printf("%lld/%lld%s",m,n,flag?")":"");
}

int main()
{
 scanf("%lld/%lld %lld/%lld", &a, &b, &c, &d);
 func(a,b); printf(" + "); func(c,d); printf(" = "); func(a*d+b*c,b*d);printf("\n");
 func(a,b); printf(" - "); func(c,d); printf(" = "); func(a*d-b*c,b*d); printf("\n");
 func(a,b); printf(" * "); func(c,d); printf(" = "); func(a*c, b*d);printf("\n");
 func(a,b); printf(" / "); func(c,d); printf(" = "); func(a*d, b*c);
 return 0;
}


注意事项:

    if(m*n==0)
    {
        printf("%s",n==0?"Inf":"0");   
        return ;            // 易错:如果分子为0,或者分母为0,输出完Inf和0之后就应该退出程序;否则扣分
    }


    bool flag=((m<0 && n>0)||(m>0 && n<0));   //易错:flag设置为bool类型

1035

插入排序:

i是数列b中第一个前一个数大于后一个数的位置
j相当于从i开始一直到b数列结束a数列与b数列完全匹配
对于插值排序:前面肯定是排好序的,也就是满足升序的序列,如果碰到前一位大于后一位则说明从此位的
后一位开始一直到数组结束都是乱序的,所以刚好用j从此位的后一位开始一直到数组结束,判断j是否为n,
如果是则为插序排列,然后对数组a进行sort排序(从头开始到i的下一位在排一次),表示他的下一次的插入排序,

归并排序:

 1.k初值为1,每次给自己乘2,
2.由于b是排序过程中的某一此序列,所以用a数列循环和b数列进行比较,flag是一个标记,初值为1,若在循环中a[j]!=b[j]则令flag为1(意思是还要进行循环)本来模拟一次就行,但是测试点要求模拟整个过程。
3.理解while的思路:
    1.首先要明确,测试点要求整个的算法是模拟归并排序的整个过程,但输出时是要通过此算法得出下一次归并
    排序的结果。
    2.首先设置flag为1进入循环,将flag默认为0,下来的for用于判断初始数列和b数列是否相同,若相同则为0,
    否则为1
    3.k自乘2,然后for循环+sort(a+i*k,a+(i+1)*2)排序,最后还要有sort(a+n/k*k,a+n);

参考代码:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int main()
{
    int n,i,j;
    cin >> n;
    int a[n],b[n];
    for(int i=0; i<n; i++)
        cin >> a[i];
    for(int j=0; j<n; j++)
        cin >> b[j];

    for(i=0; i<n-1 && b[i]<=b[i+1]; i++)
        ;
    for(j=i+1; j<n && a[j]==b[j]; j++)
        ;
    if(j==n)
    {
        cout << "Insertion Sort" << endl;
        sort(a,a+i+2);
    }
    else
    {
        cout << "Merge Sort" << endl;
        int k=1,flag=1;
        while(flag)
        {
            flag=0;
            for(int i=0; i<n; i++)
                if(a[i]!=b[i])
                    flag=1;
            k=k*2;
            for(int i=0; i<n/k; i++)
                sort(a+i*k,a+(i+1)*k);
            sort(a+n/k*k,a+n);
        }
    }

    for(int i=0; i<n; i++)
    {
        if(i!=0)
            cout << " ";
        cout << a[i];
    }
    return 0;
}


1036

参考代码:

#include<iostream>
using namespace std;
/*

*/
int main()
{
    int n;
    char c;
    cin >> n >> c;
    for(int i=0; i<n; i++)
        cout << c;
    cout << endl;
    for(int j=0; j<(n/2+n%2-2); j++)
    {
        cout << c;
        for(int k=0; k<(n-2); k++)
            cout << " ";
        cout << c << endl;
    }
    for(int i=0; i<n; i++)
        cout << c;
    return 0;
}

注意事项:

对于50%的四舍五入是:n/2+n%2。比如17而言,结果为9
但是如果只有n/2,结果为8;并非四舍五入的结果

1037

解题思路1:

1.scanf输入
2.将数字通过题中所给的进制转化,然后化为一个整数,然后计算。

参考代码1:

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
/*
    解题思路:
    1.scanf输入
    2.将数字通过题中所给的进制转化,然后化为一个整数,然后计算。
*/
int main()
{
    int a,b,c,a1,b1,c1;
    scanf("%d.%d.%d",&a,&b,&c);
    scanf("%d.%d.%d",&a1,&b1,&c1);
    int P,A;
    P=c+b*29+a*17*29;
    A=c1+b1*29+a1*17*29;
    int k=A-P;
    if(k<0)
    {
        cout << '-';
        k=abs(k);
    }
    cout << k/(17*29) << '.' << (k%(17*29))/29 << '.' << (k%(17*29))%29;
    return 0;
}

解题思路2:

1.通过诸位比较,得出:实际付的钱小于应该付的钱时,要交换顺序,保证后面减的时候,是大的减小的;并且输出
负号

2.用实际付得钱mnt-应该付的钱abc,模拟手动减

参考代码2:

#include<iostream>
#include<cstdio>
using namespace std;
int main()
{
    int a,b,c,m,n,t,x,y,z;
    scanf("%d.%d.%d %d.%d.%d",&a,&b,&c,&m,&n,&t);
    if(a>m || (a==m && b>n) || (a==m && b==n && c>t))
    {
        swap(a,m);
        swap(b,n);
        swap(c,t);
        cout << "-";
    }
    z=c>t?29+t-c:t-c;
    n=c>t?n-1:n;
    y=b>n?17+n-b:n-b;
    x=b>n?m-1-a:m-a;
    printf("%d.%d.%d",x,y,z);
    return 0;
}

注意事项:

1.abc表示应该付款值,mnt表示实际付款值,如果实际付款值小于应该付款值,则交换位置,并输出符号,因为最后都是用大的减去小的也就是用mnt-abc模拟手动减法


1038

解题思路1:

1.先输入一堆数字放到数组中,然后再输入k,随后把要查找的数放到数组中
2.然后在循环查找原来数据中要查找数字的个数,并放入数组中,最后循环输出

参考代码1:

#include<iostream>
using namespace std;
/*
    解题思路:
    1.先输入一堆数字放到数组中,然后再输入k,随后把要查找的数放到数组中
    2.然后在循环查找原来数据中要查找数字的个数,并放入数组中,最后循环输出
*/
int main()
{
    int n;
    cin >> n;
    int a[n];
    
    for(int i=0; i<n; i++)
        cin >> a[i];
        
    int k;
    cin >> k;
    int b[k],c[k]={0};
    
    for(int j=0; j<k; j++)
        cin >> b[j];
    
    for(int s=0; s<k; s++)
        for(int l=0; l<n; l++)
        {
            if(a[l]==b[s])
                c[s]++;
        }
        
    for(int i=0; i<k; i++)
    {
        if(i!=0)
            cout << " ";
        cout << c[i];
    }
    return 0;
}

解题思路2:

1.将成绩作为下标,然后对应的元素值++
2.最后直接根据输入的值,循环输出

参考代码2:

#include<iostream>
#include<vector>
#include<cstdio>
using namespace std;
int main()
{
    int n,temp;
    cin >> n;
    vector<int>b(101);
    for(int i=0; i<n; i++)
    {
        cin >> temp;
        b[temp]++;
    }
    int m;
    cin >> m;
    for(int i=0; i<m; i++)
    {
        scanf("%d", &temp);//这里要用scanf否则超时
        if(i!=0)
            printf(" ");
         printf("%d", b[temp]);
    }
    return 0;
}

注意事项:

对于for循环中有输入+输出,其实在输入时,只有敲回车,才会输出要输出的值,如果用空格将输入分开,则结果直接根据根据循环次数输出对应的值:

#include <iostream>
#include <vector>
#include<cstdio>
using namespace std;
/*
    解题思路:

*/
int main()
{
    vector<int>b(101);
    int m=4;
    int temp;
     for (int i = 0; i < m; i++)
    {
         scanf("%d", &temp);
         if (i != 0)
            printf(" ");
         printf("0");
     }
     return 0;
 }

在这里插入图片描述

在这里插入图片描述


1039

解题思路1:

1.用字符串s1,s2分别存储摊主的串珠和小红想做的串珠
2.以s2为基准,for循环,再嵌套for循环s1,如果字符相同则将s1,s2字符都改成#
3.算出s1中不为#的字符个数,算出s2中为#的字符个数,
4.if判断如果s2中#的个数等于s2的字符长度,则输出yes和s1中不为#的字符个数;如果
s2中#的个数不等于s2的字符长度,则输出剩余的字符个数

参考代码1:

#include<iostream>
using namespace std;
/*
    解题思路:
    1.用字符串s1,s2分别存储摊主的串珠和小红想做的串珠
    2.以s2为基准,for循环,再嵌套for循环s1,如果字符相同则将s1,s2字符都改成#
    3.算出s1中不为#的字符个数,算出s2中为#的字符个数,
    4.if判断如果s2中#的个数等于s2的字符长度,则输出yes和s1中不为#的字符个数;如果
    s2中#的个数不等于s2的字符长度,则输出剩余的字符个数
*/
int main()
{
    string s1,s2;
    cin >> s1 >> s2;
    for(int i=0; i<s2.length(); i++)
    {
        for(int j=0; j<s1.length(); j++)
        {
            if(s2[i]==s1[j])
            {
                s1[j]='#';
                s2[i]='#';
            }
        }
    }
    int num2=0,num1=0;
    for(int i=0; i<s1.length(); i++)
    {
        if(s1[i]!='#')
            num1++;
    }

    for(int i=0; i<s2.length(); i++)
    {
        if(s2[i]=='#')
            num2++;
    }
    if(num2==s2.length())
        cout << "Yes " << num1;
    else
        cout << "No " << s2.length()-num2;
    return 0;
}


解题思路2:

1.将字符串中的字符转化成ascii码,存储到数组book中
2.设置result为0。for循环b字符串,如果根据字符对应book中的数字,如果大于0则book–,表示
相同的字符碰掉,如果不大于0,就说原来的字符中就没有或者是用光了,则result++

3.根据result判断,如果不为0,则输出no,输出result;如果为0,则输出yes,输出原来字符串-现在字符串

参考代码2:

#include <iostream>
using namespace std;
int book[150];   //book默认值全为0
int main() 
{
/*
    解题思路:
    1.将字符串中的字符转化成ascii码,存储到数组book中
    2.设置result为0。for循环b字符串,如果根据字符对应book中的数字,如果大于0则book--,表示
    相同的字符碰掉,如果不大于0,就说原来的字符中就没有或者是用光了,则result++
    3.根据result判断,如果不为0,则输出no,输出result;如果为0,则输出yes,输出原来字符串-现在字符串
*/

     string a, b;
     cin >> a >> b;
     for (int i=0; i<a.length(); i++)
        book[a[i]]++;
     int result = 0;
     for (int i=0; i<b.length(); i++) 
     {
         if (book[b[i]] > 0)
            book[b[i]]--;
         else
            result++;
     }
     if(result!=0)
        printf("No %d", result);
     else
        printf("Yes %d", a.length()-b.length());
     return 0; 
}

1040

解题思路1:

1.先找第一个p,然后依次找A,最后找T,然后构建起来

参考代码1:

#include<iostream>
using namespace std;
/*
    解题思路:

*/
int main()
{
    int a=1000000007,num=0,o,p;
    string s;
    cin >> s;
    for(int i=0; i<s.length(); i++)
    {
        if(s[i]=='P')
        {
            o=i;
            for(int j=i+1; j<s.length(); j++)
            {
                if(s[j]=='A')
                {
                    p=j;
                    for(int k=j+1; k<s.length(); k++)
                    {
                        if(s[k]=='T')
                            num++;
                    }
                }
            }
        }
    }
    cout << num%a;
    return 0;
}

解题思路2:

1.要知道PAT的个数等于对于每一个A,A前P的个数A后T的个数累加起来即为PAT的个数
2.先循环遍历T的个数
3.for循环,若遇到P,则countp++,如果遇到A,则直接用countPcoutT累加到result,如果遇到T,则countT–,
4.最后不要忘记对1000000007求余

参考代码2:

#include <iostream>
#include <string>
using namespace std;
/*
    解题思路:
    1.要知道PAT的个数等于对于每一个A,A前P的个数*A后T的个数累加起来即为PAT的个数
    2.先循环遍历T的个数
    3.for循环,若遇到P,则countp++,如果遇到A,则直接用countP*coutT累加到result,如果遇到T,则countT--,
    4.最后不要忘记对1000000007求余
*/
int main()
{
     string s;
     cin >> s;
     int len=s.length(), result=0, countp=0, countt=0;
     for(int i=0; i<len; i++)
     {
         if (s[i]=='T')
         countt++;
     }
     for (int i=0; i<len; i++)
     {
         if (s[i]=='P')
            countp++;
         if (s[i] == 'T')
            countt--;
         if (s[i] == 'A')
            result=(result+(countp * countt))%1000000007;
     }
     cout << result;
     return 0;
 }
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值