pat 乙级 1081~1090

文章目录

1081
1082
1083
1084
1085
1086
1087
1088
1089
1090


1081

解题思路:

1.for循环先输入字符串,然后if-else判断如果字符串长度>=6,则进入下一步;否则就输出字符串太短了
2.设置3个int类型且初值为0的三个变量int invalid = 0, hasAlpha = 0, hasNum = 0;
3.if-else if-else if构建:
      1.如果字符不是小数点也不是字母和数字,设置invalid为1,最后根据invalid的值为1,来输出太乱了
      2.进入第一个else if,如果字符是字母,则设置hasAlpha为1,最后根据hasAlpha的值为0,来输出缺少字母
      3.进入第二个else if,如果字符是数字,则设置hasNum为1,最后根据hasNum的值为0,来输出缺少数字
      4.如果没有以上情况,就输出完美

参考代码:

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

*/
int main()
{
     int n;
     cin >> n;
     getchar();   //接受缓冲区的回车,
     for (int i = 0; i < n; i++)
     {
         string s;
         getline(cin, s);
         if (s.length() >= 6)
         {
             int invalid = 0, hasAlpha = 0, hasNum = 0;
             for (int j = 0; j < s.length(); j++)
             {
                 if (s[j] != '.' && !isalnum(s[j]))
                    invalid = 1;
                 else if
                    (isalpha(s[j]))
                        hasAlpha = 1;
                 else if (isdigit(s[j]))
                    hasNum = 1;
             }
             if (invalid == 1)
                cout << "Your password is tai luan le.\n";
             else if (hasNum == 0)
                cout << "Your password needs shu zi.\n";
             else if (hasAlpha == 0)
                cout << "Your password needs zi mu.\n";
             else
                cout << "Your password is wan mei.\n";
         }
        else
            cout << "Your password is tai duan le.\n";
     }
     return 0;
 }

知识总结:

1.如果用cin输入数字,紧接用getline输入,必须在二者之间加入getchar(),否则就在输入完数字后程序结束
#include <iostream>
#include <cctype>
using namespace std;

int main()
{
     int n;
     cin >> n;
     //getchar();    //
     string s;
     getline(cin,s);

     return 0;
 }
2.isalnum)用来判断字符是数字或者字母?是,返回true;否则,返回false
3.isalpha()用来判断字符是纯字母?是,返回true;否则,返回false
4.isdigit()用来判断字符是数字?是,返回true;否则,返回false

1082

解题思路1:

1.先计算两个数字的平方和dis
2.找出最大数字所对应的运动员编号
3.找出最小数字所对应的运动员编号
4.每次更新最大,最小值
5.输出

参考代码:

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

*/
int main()
{
     int n, id, x, y, maxid, maxdis = -1, minid, mindis = 99999;
     cin >> n;
     for (int i = 0; i < n; i++)
     {
         cin >> id >> x >> y;
         int dis = x * x + y * y;
         if (dis > maxdis)
            maxid = id;
         if (dis < mindis)
            minid = id;
         maxdis = max(maxdis, dis);   
         mindis = min(mindis, dis);
     }
     printf("%04d %04d", minid, maxid);
     return 0;
 }


知识总结:

1.max函数,min函数
#include <iostream>
using namespace std;
int main()
{

    int a=5,b=3;
     cout << min(a,b);  //输出a,b中较小的值
     cout << max(a,b);   //输出a,b中较大的值

     return 0;
 }

解题思路2:

1.设置一个结构数组,并输入
2.通过循环找出求两个数字平方和的最大值下标和最小值下标
3.最后根据下标输出编号

参考代码2:

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

*/
struct su
{
    int a,b,c;
};
int main()
{
    int n,max=0,min=0,max1=-1,min1=100003;
    cin >> n;
    su a[n];
    for(int i=0; i<n; i++)
        cin >> a[i].a >> a[i].b >> a[i].c;
    for(int i=1; i<n; i++)
    {
        if(a[i].b*a[i].b+a[i].c*a[i].c > a[max].b*a[max].b+a[max].c*a[max].c)
            max=i;
        if(a[i].b*a[i].b+a[i].c*a[i].c < a[min].b*a[min].b+a[min].c*a[min].c)
            min=i;
    }
   printf("%04d %04d",a[min].a,a[max].a);
}


1083

解题思路1:

1.设置一个长度为10000的数组a
2.将其计算结果作为数组下标,元素值++
3.从后向前输出,如果元素值>=2,则输出对应的下标也就是之前算的差值,并且再输出其元素值

参考代码1:

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

*/
int main() 
{
     int n, t, a[10000] = {0};
     cin >> n;
     for (int i = 1; i <= n; i++) 
     {
         cin >> t;
         a[abs(t-i)]++;
     }
     for (int i = 9999; i >= 0; i--)
        if (a[i] >= 2) 
            cout << i << " " << a[i] << endl;
     return 0; 
 }


解题思路2:

1.定义一个vector数组,然后计算与下标相减再减1,
2.对vector数组进行降序排列
3.循环输出重复出现>=2次的数,及其重复次数。(思想就是:每次取出第一个,然后与后面的值比较统计其重复次数)

参考代码2:

#include<iostream>
#include<cmath>
#include<vector>
#include<algorithm>
/*
    

*/
using namespace std;
bool cmp(int a,int b)
{
    return a>b;
}
int main()
{
    int n;
    cin >> n;
    vector<int>a(n);
    for(int i=0; i<n; i++)
    {
        cin >> a[i];
        a[i]=abs(a[i]-i-1);
    }
    sort(a.begin(),a.end(),cmp);
    int temp=a[0],cnt=1;
    for(int i=1; i<n; i++)
    {
        if(temp==a[i])
            cnt++;
        else
        {
            if(cnt>=2)
                cout << temp << " " << cnt << endl;
            temp=a[i];
            cnt=1;
        }
    }
    if(cnt>=2)
        cout << temp << " " << cnt << endl;
    return 0;
}


1084

解题思路1:

1.zhuanhua()函数是将数字转化为字符串
2.xinzhi()函数是每次返回统计后的字符串(就像前面说的一样,统计重复出现的字符串个数)
3.main走一个循环即可

参考代码1:

#include<iostream>
#include<string>
#include<sstream>
using namespace std;
/*
    解题思路;
    1.用字符串s来报存,改变s,
*/
string zhuanhua(int a)
{
    string s;
    stringstream ss;
    ss << a;
    ss >> s;
    return s;
}
string xinzhi(string s)
{
    string num,s1;
    num+=s[0];
    int cnt=1;
    for(int i=1; i<s.length(); i++)
    {
        if(num[0]==s[i])
            cnt++;
        else
        {
            s1=s1+num+zhuanhua(cnt);
            num="";
            num+=s[i];
            cnt=1;
        }
    }
    s1=s1+num+zhuanhua(cnt);
    return s1;
}
int main()
{
    string s;
    int a;
    cin >> s >> a;
    for(int i=1; i<a; i++)
    {
        xinzhi(s);
        s=xinzhi(s);
    }
    cout << s;
}

解题思路2:

1.三层for循环,外层for是第n个;第2层for和第3层的作用就是比如:前面一个值是1121 通过此5行代码 就变成 122111
2.第二层for与第三层for:
      1.以字符串的长度循环,但是循环的增量是i=j也就是下一小段相同字符串的第一个字符的位置
      2.第3层for,j=i从这个位置开始,如果后面的字符和前面的相同,则j++统计相同字符的个数
      3.最后将字符和相同字符的个数加到临时字符串变量t中

参考代码2:

#include <iostream>
using namespace std;
int main()
{
     string s;
     int n, j;
     cin >> s >> n;
     for (int cnt = 1; cnt < n; cnt++)   //控制它的循环次数
     {
         string t;        //临时变量t
         for (int i = 0; i < s.length(); i = j)   //此行代码开始向下5行的作用就是
         {
             for (j = i; j < s.length() && s[j] == s[i]; j++)
                     ;  //统计相同字符的个数
                t += s[i] + to_string(j - i);   //+的优先级> +=  t表示前一个字符的结果,s[i]当前每一小段字符,to_string(j-i)实质表示相同字符的个数
         }
         s = t;
     }
     cout << s;
     return 0;
 }

知识总结:

1.将数字转化为字符串
to_string(123); //表示将数字123转化为字符串123

注意事项:

1.切记第3层for的循环语句是 ; 这个循环的目的是统计相同字符的个数
2.由于第2层的循环增量是i=j,所以要提前定义变量j,并且在第3层for的循环中,不能再定义临时变量j


1085

解题思路1:

1.设置一个结构node,cmp排序
2.设置两个map类型
3.for循环输入信息
      1.根据学校,将其字符串所有字符改为小写
      2.每次根据题型算出对应的分数
      3.以学校名为关键字,sum中成绩累加,cnt中人数累加
4.设置一个数组结构,将sum和cnt中的信息导入进数组结构,并且对数组结构进行cmp
5.按照要求输出

参考代码:

#include <iostream>
#include <algorithm>
#include <vector>
#include <map>
/*
    解题思路:

*/
using namespace std;
struct node
{
 string school;
 int tws, ns;     //tws就是总分,ns就是人数
};

bool cmp(node a, node b)
{
 if (a.tws != b.tws)    //如果总分不同,按照总分的降序排列
 return a.tws > b.tws;
 else if (a.ns != b.ns)  //如果总分相同,按照人数的升序排列
 return a.ns < b.ns;
    else
 return a.school < b.school;  //如果总分,人数相同,按照学校名的升序排列
 }

int main()
{
     int n;
     cin >> n;
     map<string, int> cnt;
     map<string, double> sum;
     for (int i = 0; i < n; i++)
     {
         string id, school;
         cin >> id;
         double score;
         cin >> score;
         cin >> school;

         for (int j = 0; j < school.length(); j++)
            school[j] = tolower(school[j]);

         if (id[0] == 'B')
            score = score / 1.5;
         else if (id[0] == 'T')
            score = score * 1.5;
         sum[school] += score;  //计算不同学校对应的总分
         cnt[school]++;       //统计人数
     }

     vector<node> ans;  //将信息放到ans数组结构中
     for (auto it = sum.begin(); it != sum.end(); it++)  //设置迭代器,将对应的信息放到ans中
        ans.push_back(node{it->first, (int)sum[it->first], cnt[it->first]});

     sort(ans.begin(), ans.end(), cmp);  //按照要求排序


     int rank = 0, pres = -1;
     cout << ans.size() << endl;

     for (int i = 0; i < ans.size(); i++)  //如果成绩不同,则按照i+1输出; 否则不变其排名
     {
         if (pres != ans[i].tws)
            rank = i + 1;
         pres = ans[i].tws;
         printf("%d ", rank);

         cout << ans[i].school;
         printf(" %d %d\n", ans[i].tws, ans[i].ns);
     }
     return 0;
 }

知识总结:

1.将字符串中的每个字符改为小写
#include<iostream>
using namespace std;
int main()
{
    string s;
    cin >> s;
    for(int i=0; i<s.leng(); i++)
        s[i]=tolower(s[i]);
}
`
2.如果对vector中的三个信息需要比较的话,应该用if-else去设置
bool cmp(node a, node b)
{
 if (a.tws != b.tws)    //如果总分不同,按照总分的降序排列
 return a.tws > b.tws;
 else if (a.ns != b.ns)  //如果总分相同,按照人数的升序排列
 return a.ns < b.ns;
    else
 return a.school < b.school;  //如果总分,人数相同,按照学校名的升序排列
 }

1086

参考代码1:

#include<iostream>
#include<sstream>
using namespace std;

int main()
{
    int a,b;
    cin >> a >> b;
    string s;
    stringstream ss;
    ss << a*b;
    ss >> s;
    for(int i=s.length()-1; i>=0; i--)
        cout << s[i];
}

参考代码2:

#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
    int a,b;
    cin >> a >> b;
    string s;
    s=to_string(a*b);
    reverse(s.begin(),s.end());
    cout << stoi(s);
}

知识总结2:

1.将数字转换为字符串
    s=to_string(a*b);
2.扭转字符串
    reverse(s.begin(),s.end());
3.将数字字符串转化为数字
cout << stoi(s);

注意事项:

1.要注意最后将字符串一定转化为数字,否则有的测试点过不去


1087

参考代码:

#include<iostream>
#include<set>
using namespace std;
int main()
{
    int n;
    cin >> n;
    set<int> s;
    for(int i=1; i<=n; i++)
        s.insert(i/2+i/3+i/5);
    cout << s.size();
    return 0;
}


1088

解题思路1:

1.将甲的值从99~1开始递减循环
2.先算出jia,yi,bing三个值,然后进行判断一但有满足条件的就退出
3.后面按照题意输出

参考代码1:

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

*/
int main()
{
    int x,y,my;
    cin >> my >> x >> y;
    int jia=0,yi,bing;
    for(jia=99; jia>=1; jia--)
    {
        yi=jia%10*10+jia/10;
        if(abs(jia-yi)%x==0)
            bing=abs(jia-yi)/x;
        if(bing!=0 && yi==bing*y)
        {
            break;
        }
    }
    if(jia==0)
    {
        cout << "No Solution";
        return 0;
    }
    else
    {
        string s=jia>my?"Cong":jia==my?"Ping":"Gai";
        string s1=yi>my?"Cong":yi==my?"Ping":"Gai";
        string s2=bing>my?"Cong":bing==my?"Ping":"Gai";
        cout << jia << " " << s << " " << s1 << " " << s2;
return 0;
    }

    return 0;
}

解题思路2:

1.输出m,x,y三个值
2.还是jia的值从99~10递减循环
3.计算出yi的值
4.切记将bing的值设为double类型
5.判断是否满足条件,满足就输出,然后return 0
6.最后再输出"No Solution"

参考代码2:

#include<iostream>
#include<cmath>
using namespace std;
int jia,yi,my;
double bing;
void print(double m)  //这个m由于还有bing的值,所以设置为double类型
{
    if(m==my)
        cout << " Ping";
    else if(m>my)
        cout << " Cong";
    else
        cout << " Gai";
}
int main()
{
    int x,y;
    cin >> my >> x >> y;
    for(jia=99; jia>=10; jia--)
    {
        yi=jia%10*10+jia/10;
        bing=abs(jia-yi)*1.0/x;
        if(yi==bing*y)
        {
            cout << jia;
            print(jia);
            print(yi);
            print(bing);
            return 0;
        }
    }
    cout << "No Solution";
    return 0;
}

1089

解题思路1:

1.使用v数组来存放实时情况

2.3层for循环嵌套:
      1.前2层循环是假设i,j=i+1是狼人,这样来最后判断出谁是狼人
      2.在第2层for循环中要设置vector类型的数组lie,a分别表示说谎人的编号和人员成分的数组(意思是如下图所示)
      3.第3层for循环用来判断2个说谎人的编号,将其放到lie数组中
      4.如果lie的长度是2表示有2个说谎的人,并且说谎人的编号在数组a中对应的值相加为0,因为一个说谎的是狼人,那另一个说谎的好人,所以相加为0
      5.至于有多个值,按照最小序列输出;本来就是i从1开始,并且j=i+1一直的证到n(也是从小到大)

在这里插入图片描述

参考代码:

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

*/
int main()
{
     int n;
     cin >> n;
     vector<int> v(n+1);

     for (int i = 1; i <= n; i++)
        cin >> v[i];     //v数组表示的是实时情况

     for (int i = 1; i <= n; i++)
     {
         for (int j = i + 1; j <= n; j++)
         { //a数组表示的就对应的编号是狼人,还是好人
             vector<int> lie, a(n + 1, 1);   //a是一个长度为n+1,并且初始值全为1的数组
             a[i] = a[j] = -1;  //1表示好人;-1表示狼人
             for (int k = 1; k <= n; k++)   //k从1~n分别判断k所说的是真是假
                if (v[k] * a[abs(v[k])] < 0) //k说的话和真实情况不同(v[k] * a[abs(v[k])] < 0)则表示k在说谎,将k放在lie数组中
                    lie.push_back(k);   // lie数组表示将说谎人的编号
             if (lie.size() == 2 && a[lie[0]] + a[lie[1]] == 0)  //如果说谎人数等于2并且这两个说谎的人一个是好人一个是狼人
            {//a[lie[0]] + a[lie[1]] == 0表示的意思是两个狼人中一个说谎一个说真话
                 cout << i << " " << j;
                 return 0;
            }
         }
     }
     cout << "No Solution";
     return 0;
}

1090

解题思路:

1.设置一个map类型的vector的数组,每次输入两个值,其中一个为关键字,另一个为元素值,在反过来设置下
2.根据k循环
      1.cnt表示运输货物的个数,flag就是一个标签,a是以货物编号为下标,元素值初始都为0,但是将要运输的货物的
元素值设为1
      2.双层for循环:
            1.第一层以要运输的货物个数为准
            2.第2层for是以与每个运输货物不相容的货物个数为下标,然后判断a[m[v[i]][j]]是否为1,为1表示运输的货物中有不相容的
最后按要求输出

参考代码:

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

*/
int main() 
{
     int n, k, t1, t2;
     map<int,vector<int>> m;
     scanf("%d%d", &n, &k);
     for (int i = 0; i < n; i++)   //设置一个关键字是int类型的值,它下面是一个vector的数组
     {
         scanf("%d%d", &t1, &t2);
         m[t1].push_back(t2);
         m[t2].push_back(t1);
     }
     while (k--) 
     {
         int cnt, flag = 0, a[100000] = {0};  //0表示不相容
         scanf("%d", &cnt);
         vector<int> v(cnt);
         for (int i = 0; i < cnt; i++) 
         {
             scanf("%d", &v[i]);     //v[i]是运输货物的编号
             a[v[i]] = 1;          //此行代码的意思是将所有要运输的货物下标设为1,其余都是0
         }
     
         for(int i=0; i<v.size(); i++)     //第一层for遍历循环每个要运输的货物
            for(int j=0; j<m[v[i]].size(); j++)  //第2层for是看每个要运输的货物,下面有哪些不相容的物体,在对应回去a数组的元素看是否为之前设置的1,如果是表示不相容flag=1
                if (a[m[v[i]][j]] == 1) 
                    flag = 1;
         printf("%s\n",flag?"No":"Yes");  //如果flag为1表示不相容,如果flag为0表示想容
     }
     return 0;
}

知识总结:

1.对于需要有一个值作为关键字,然后其后对应多个值,可以设置为map类型,代码如下:
map<int,vector<int>> m;   //设置一个关键字为int类型,然后下面是一个vector的数组
2.如果用while对于某一个值cnt来循环,可以设置为
while(cnt--)
{}
3.对于给vector数组输入值时,最好提前设置好vector的长度,这样可以保证全部输入进去
         scanf("%d", &cnt);
         vector<int> v(cnt);
         for (int i = 0; i < cnt; i++) 
         {
             scanf("%d", &v[i]);     //v[i]是运输货物的编号
    
         }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值