pat 乙级 1061~1070

文章目录

1061
1062
1063
1064
1065
1066
1067
1068
1069
1070


1061

解题思路1:

1.设置3个数组manfen,biaoda,xueda
2.先输入进去manfen,biaoda
3.双层for循环,输入学生答案,与biaoda对比,如果一样则sum累加manfen,循环完后输出

在这里插入图片描述

参考代码:

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

*/
int main()
{
    int n,m;
    cin >> n >> m;
    int manfen[m],biaoda[m],xueda[m];
    for(int i=0; i<m; i++)
        cin >> manfen[i];
    for(int i=0; i<m; i++)
        cin >> biaoda[i];

    for(int i=0; i<n; i++)
    {
        int sum=0;
        for(int j=0; j<m; j++)
        {
            int temp;
            cin >> temp;
            if(temp==biaoda[j])
                sum+=manfen[j];
        }
        cout << sum << endl;
    }
    return 0;
}

1062

解题思路1:

1.先找M1,M2的最小公倍数S1,然后在找S1与K的最小公倍数K1
2.通分,将N1变为L1,将N2变为L2
3.找L1~L2之间找K1/K的倍数
4.写一个将分数化为最简分数的函数huajian,对于上面所有找的值进行化简,判断其分母是否为K,是则输出;不是
则不输出

参考代码1:

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

*/
int zuiyin(int a,int b)
{

    int max=-1;

    if(a>b && a%b==0)
        return b;
    else if(a<b && b%a==0)
        return a;
    int temp=a>b?b:a;
    for(int i=1; i<temp; i++)
    {
        if(a%i==0 && b%i==0)
            if(i>max)
                max=i;
    }
    return max;
}
int main()
{
    int N1,N2,M1,M2,L1,L2,K;
    scanf("%d/%d %d/%d %d",&N1,&M1,&N2,&M2,&K);
    int S1=M1*M2/zuiyin(M1,M2);
    int K1=K*S1/zuiyin(S1,K);
    L1=K1/M1*N1;
    L2=K1/M2*N2;
    int flag=0;
    for(int i=L1+1; i<L2; i++)
        if(i%(K1/K)==0)
            if(zuiyin(i,K1)==K1/K)
            {
                if(flag!=0)
                    cout << " ";
                printf("%d/%d",i/(K1/K),K);
                flag++;
            }
    return 0;
}

解题思路2:

1.不用找M1,M2,K的最大公约数。
2.用分母相乘的方法,先找到 num/K 比N1/M1大的最小num
3.用while循环,也是用分母相乘的方法,找到所有num/k 小于 N2/M2,同时判断num与k之间的最大公约数是否为1 是就输出
4.详见如下图

在这里插入图片描述

参考代码2:

#include<iostream>
using namespace std;

int gcd(int a, int b)
{
    return b==0?a:gcd(b,a%b);
}


int main()
{
    int n1,m1,n2,m2,k;
    scanf("%d/%d %d/%d %d",&n1,&m1,&n2,&m2,&k);

    if(n1*m2>m1*n2)
    {
        swap(n1,n2);
        swap(m1,m2);
    }

    int num=1;
    while(n1*k>=m1*num)
        num++;
    int flag=0;
    while(num*m2<k*n2)
    {
        if(gcd(num,k)==1)
        {
            if(flag!=0)
                cout << " ";
            printf("%d/%d",num,k);
            flag++;
        }
        num++;
    }
    return 0;
}

知识总结:

1.求最大公约数—辗转相除法
int gcd(int a, int b)
{
    return b==0?a:gcd(b,a%b);
}

1063

参考代码:

#include<iostream>
#include<cmath>
#include<cstdio>
using namespace std;

int main()
{
    double max=-1.0,temp,temp1,temp2;
    int n;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        cin >> temp1 >> temp2;
        temp=sqrt(temp1*temp1+temp2*temp2);
        if(temp>max)
            max=temp;
    }
    printf("%.2f",max);
    return 0;
}



1064

解题思路:

1.对于每一个输入的数字,求其每个位上的数字和
2.将其insert入set类型a中

参考代码:

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

    

*/
int main()
{
    int n;
    cin >> n;
    int flag=0;
    set<int>a;
    set<int>::iterator ita;
    for(int i=0; i<n; i++)
    {
        int temp;
        cin >> temp;
        int num=0;
        while(temp!=0)
        {
            num+=temp%10;
            temp/=10;
        }
        a.insert(num);
    }
    cout << a.size() << endl;
    for(ita=a.begin(); ita!=a.end(); ita++)
    {
        if(flag!=0)
            cout << " ";
        cout << *ita;
        flag++;
    }
    return 0;
}

知识总结:

1.用set类型来存储值,一方面数字是按升序排列,另一方面在存储时是没有重复的插入

1065

解题思路1:

1.设置一个couple数组来存放夫妻ID,下标为a中存放b;下标为b中存放a
2.设置guest来存放参加晚会的ID,如果参见晚会的人有对象,则在isExist数组中存放参见晚会的人的对象值为1表示参加晚会的人的对象的对象来参加晚会了,如下图所示
3.要删除isExist中值为1的元素,保存值为0的元素
4.最后按要求输出

参考代码1:

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

*/
int main()
{
     int n, a, b, m;
     cin >> n;
     vector<int> couple(100000, -1);   //设置一个长度为100000,初值为-1的数组couple , 设置数组长度为100000是因为数组下标是00000~99999

     for (int i = 0; i < n; i++)   //将配对的数字,一个做下标,一个做元素值
     {
         scanf("%d%d", &a, &b);
         couple[a] = b;
         couple[b] = a;
     }

     cin >> m;
     vector<int> guest(m), isExist(100000);   //isExist也是数组长度为100000,因为下标也是从00000~99999

     for (int i = 0; i < m; i++)  //将所有输入的客人的配偶做下标,值设为1
     {
         cin >> guest[i];
         if (couple[guest[i]] != -1)
            isExist[couple[guest[i]]] = 1;
     }

     set<int> s;
     for (int i = 0; i < m; i++)    //主要删除此人及配偶
     {
         if (!isExist[guest[i]])
            s.insert(guest[i]);
     }
     printf("%d\n", s.size());
     for (auto it = s.begin(); it != s.end(); it++)
     {
         if (it != s.begin())
            printf(" ");
         printf("%05d", *it);
     }
     return 0;
}

解题思路2:

1.设置一个2列,n行的一个二维数组来存储夫妻对数
2.b来存放参加晚会的人
3.xunzhao函数表示如果此人有对象则返回其对象的下标,如果此人没对象则返回100000
4.循环b结合xunzhao函数,如果参加晚会的人有对象,继续在b中查找其对象是否存在,若存在则删除此人及其对象
5.最后按要求输出
6.可惜超时

参考代码2:

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

*/
int a[50001][2];
int n;
int xunzhao(int temp)  //对a而言,如果在二维数组中没有就返回0,如果有就返回其对应的值
{
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<2; j++)
        if(a[i][j]==temp)
            if(j==0)
                return a[i][1];
            else
                return a[i][0];
    }
    return 100000;
}
int main()
{
    cin >> n;
    for(int i=0; i<n; i++)
        for(int j=0; j<2; j++)
            cin >> a[i][j];
    set<int> b;
    set<int>::iterator itb;
    int m,flag=0;
    cin >> m;
    for(int i=0; i<m; i++)
    {
        int temp;
        cin >> temp;
        b.insert(temp);
    }
    //消除在此set中有配偶的
    for(itb=b.begin(); itb!=b.end(); itb++)
    {
        if(xunzhao(*itb)!=100000)
            if(b.find(xunzhao(*itb))!=b.end())
            {
                b.erase(xunzhao(*itb));
                b.erase(*itb);
            }
    }
    cout << b.size() << endl;
    for(itb=b.begin(); itb!=b.end(); itb++)
    {
        if(flag!=0)
            cout << " ";
        cout << *itb;
        flag++;
    }
    return 0;
}



1066

参考代码1:

#include<iostream>
using namespace std;
int main()
{
    int m,n,a,b,k;
    cin >> m >> n >> a >> b >> k;
    int l[n];
    for(int i=0; i<m; i++)
    {
        for(int j=0; j<n; j++)
            cin >> l[j];
        for(int j=0; j<n; j++)
        {
            if(j!=0)
                cout << " ";
            if(l[j]<a || l[j]>b)
                printf("%03d",l[j]);
            else
                printf("%03d",k);
        }
        cout << endl;
    }
    return 0;
}


参考代码2:

#include<iostream>
using namespace std;
int main()
{
    int m,n,a,b,k,temp;
    cin >> m >> n >> a >> b >> k;
    for(int i=0; i<m; i++)
    {
        for(int j=0; j<n; j++)
        {
            scanf("%d",&temp);              //不用设置数组来存放,因为在循环中如果有一个输入,一个输出,如果一次性全部输入,那么对应的输出也是一次性全部输出,并非输入一个就显示一个。这里如果用cin输入就会超时
            if(temp>=a && temp<=b)
                temp=k;
            if(j!=0)
                cout << " ";
            printf("%03d",temp);
        }
        cout << endl;
    }
    return 0;
}

1067

解题思路1:

1.while设置为死循环
2.还是输入一个,输出一个,不是等到全部输入完后在输出
3.如果是正确的密码且尝试次数不超过 N,则在一行中输出 Welcome in,并结束程序;
如果是错误的,则在一行中按格式输出 Wrong password: 用户输入的错误密码;
当错误尝试达到 N 次时,再输出一行 Account locked,并结束程序
就按照这个策略去构建代码,不要自己胡推

参考代码1:

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

*/
int main()
{
     string password, temp;
     int n, cnt = 0;
     cin >> password >> n;
     getchar();
     while(1)
     {
         getline(cin, temp);
         if (temp == "#")
          break;
         cnt++;
         if (cnt <= n && temp == password)
         {
             cout << "Welcome in";
             break;
         }
         else if (cnt <= n && temp != password)
         {
             cout << "Wrong password: " << temp << endl;
             if (cnt == n)
             {
                 cout << "Account locked";
                 break;
             }
         }
     }
     return 0;
 }

注意事项:

1.在上面代码中不要忘记在第一次输入完后再输入getchar()接受缓冲区中的回车,以方便后面在循环中继续输入
2.此题的思路并非等所有输入完后在输出

解题思路2:

1.如果是正确的密码且尝试次数不超过 N,则在一行中输出 Welcome in,并结束程序
2.如果是错误的,则在一行中按格式输出 Wrong password: 用户输入的错误密码
3.当错误尝试达到 N 次时,再输出一行 Account locked,并结束程序。
4.用while开始输入,统计当前输入的个数,

参考代码2:

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


*/
int main()
{
    string mima,temp="ds";
    int n,count=1;
    cin >> mima >> n;
    scanf("\n");
    vector<string> a;
    while(temp.compare("#")!=0)
    {
        getline(cin,temp);
        a.push_back(temp);
    }
    for(int i=0; i<a.size(); i++)
    {
        if(a[i].compare(mima)!=0 && count<=n)
        {
             printf("Wrong password: ");
             cout << a[i] << endl;
        }

        if(a[i].compare(mima)!=0 && count>n)
        {
             cout << "Account locked";
             return 0;
        }

        if(a[i].compare(mima)==0 && count>n)
        {
             cout << "Account locked";
             return 0;
        }

        if(a[i].compare(mima)==0)
        {
            cout << "Welcome in";
            return 0;
        }
        count++;
    }
    return 0;
}

1068

解题思路1:

1.第一行和第1列肯定都不要想,最后一行,一列的值也不要想
2.还是用二维数组去存储
3.用该值去见上下的,左右的,主队角线上的,副对角线上的差值必须大于tol才行

参考代码1:

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

*/
int main()
{
    int m,n,tol,cnt=0,s,b;
    cin >> m >> n >> tol;
    int a[n][m];
    for(int i=0; i<n; i++)
    {
        for(int j=0; j<m; j++)
            cin >> a[i][j];
    }
    for(int i=1; i<n-1; i++)
    {
        for(int j=1; j<m-1; j++)
        {
            if(a[i][j]-a[i][j-1]>tol && a[i][j]-a[i][j+1]>tol && a[i][j]-a[i-1][j]>tol && a[i][j]-a[i+1][j]>tol && a[i][j]-a[i-1][j-1]>tol && a[i][j]-a[i+1][j+1]>tol && a[i][j]-a[i-1][j+1]>tol && a[i][j]-a[i+1][j-1]>tol)
            {
                s=i;
                b=j;
                cnt++;
            }
        }
    }
    if(cnt==1)
        printf("(%d, %d): %d",b+1,s+1,a[s][b]);
    else if(cnt>1)
        cout << "Not Unique";
    else if(cnt==0)
        cout << "Not Exist";

    return 0;
}

解题思路2:

1.设置一个2维数组v,dir表示该点周围的8个点的位置(按照顺时针的顺序)
2.判断该点是否符合要求的函数judge
     1.循环是8次
      2.i,j分别表示行和列
     3.tx,ty分别表示i,j周围的点的坐标
     4.tx取值范围是0–n-1,ty取值范围是0–m-1,v[i][j]-v[tx][ty]<=tol或者v[i][j]-v[tx][ty]>=-tol,返回false

3.将2维数组设为n行m列的数组
4.按照行-列的顺序依次输入,并且mapp[i][j]++,表示该数字必须只有1个
5.用双层for循环统计符合要求的数字的个数cnt
6.最后根据cnt的值按要求输出

参考代码2:

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

*/
int m, n, tol;
vector<vector<int>> v;
int dir[8][2] = {{-1, -1}, {-1, 0}, {-1, 1}, {0, 1}, {1, 1}, {1, 0}, {1, -1},{0, -1}};

bool judge(int i, int j)
{
     for (int k = 0; k < 8; k++)
     {
         int tx = i + dir[k][0];    //行,下面代码中i是从0~n-1
         int ty = j + dir[k][1];   //列,下面代码中j是从0~m-1
         //tx,ty分别表示周围8个点的坐标,它的意思是直接判断这些坐标所代表的值是否符合要求,自动排除了,所有第1行(列),最后1行(列)的点
         if (tx >= 0 && tx < n && ty >= 0 && ty < m && v[i][j] - v[tx][ty] >= 0 - tol && v[i][j] - v[tx][ty] <= tol)
            return false;
     }
     return true;
 }

int main()
{
     int cnt = 0, x = 0, y = 0;
     cin >> m >> n >> tol;              //m是列,n是行
     v.resize(n, vector<int>(m));          //resize(),设置大小(size); 设置一个n行,每一行放一个长度为m的数组
     map<int, int> mapp;
     
     for (int i = 0; i < n; i++)
     {
         for (int j = 0; j < m; j++)
         {
             cin >> v[i][j];
             mapp[v[i][j]]++;   //这个mapp表示比如在输入样例1中 0有8个,65280有23个。。。
         }
     }
     
     
     for (int i = 0; i < n; i++)
     {
         for (int j = 0; j < m; j++)
         {
             if (mapp[v[i][j]] == 1 && judge(i, j) == true)
             {
                 cnt++;
                 x = i + 1;
                 y = j + 1;
             }
         }
     }
     

 }

注意事项:

1.其实并不是所有第1行(列),最后1行(列)的点不考虑,这些点只与剩下的3或者5个点比较
2.对于输入样例1,其实16711479和16711680都合适,为啥结果只有16711680,因为16711479满足条件的有2个


1069

解题思路1:

1.先判断输入的字符串在之前是否存在,如果是就s=s+1(s表示要输出的位置)

2.当i==s时,并且这个位置的字符串之前没有
      1.先mapp[str]设为1
      2.输出
      3.改变合适的位置s
      4.设置一个flag初值为0,如果有中奖的则把flag改为1
3.当循环结束时,根据flag的值看是否输出Keep going…

参考代码:

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

*/
int main()
{
     int m, n, s;
     cin >> m >> n >> s;
     string str;
     map<string, int> mapp;
     bool flag = false;
     for (int i = 1; i <= m; i++)
     {
         cin >> str;
         if (mapp[str] == 1)
            s+=1;
         if (i == s && mapp[str] == 0)  //按照规定的间隔输出,还要保证之前没有得过奖
         {
             mapp[str] = 1;
             cout << str << endl;
             flag = true;
             s+=n;
         }
     }
     if (flag == false)
        cout << "Keep going...";
     return 0;
 }


1070

解题思路:

1.将这个数字排序

2.从最小的两个开始就一路计算

参考代码:

/*
    解题思路:

*/
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int n;
    cin >> n;
    int a[n];
    for(int i=0; i<n; i++)
        cin >> a[i];
    sort(a,&a[n]);             //默认为从小到大
    double sum=(double)(a[0]+a[1])/2;
    for(int i=2; i<n; i++)
    {
        sum=(sum+a[i])/2;
    }
    cout << (int)sum;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PAT乙级1009题是一个关于字符串处理的题目。根据题目要求,我们需要将输入的字符串按照单词的逆序输出。根据提供的引用内容,我们可以看到有三种不同的解法。 引用\[1\]和引用\[2\]是两个相似的解法,使用了字符串处理函数strchr和strrchr来定位空格字符,并将字符串分割成单词。然后通过循环输出单词,最后输出剩余的最后一个单词。 引用\[3\]是另一种解法,使用了二维数组来存储每个单词。通过循环读取输入的字符串,直到遇到换行符为止。然后通过倒序循环输出每个单词。 根据题目要求,你可以选择其中一种解法来完成PAT乙级1009题。 #### 引用[.reference_title] - *1* [PAT考试乙级1009(C语言实现)](https://blog.csdn.net/JeffreyDDD/article/details/78395267)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [PAT乙级1009(C语言实现)](https://blog.csdn.net/weixin_62870950/article/details/124934829)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [PAT乙级测试题1009(C语言实现)](https://blog.csdn.net/weixin_45947840/article/details/105943475)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值