pat 乙级 1091~1095

文章目录

1091
1092
1093
1094
1095


1091

参考代码:

#include<iostream>
using namespace std;
/*
    解题思路:
    1.让j的值从小到大开始排列
    2
*/
int fanhui(int a)
{
    int b=1;
    while(a!=0)
    {
       b*=10;
       a/=10;
    }
    return b;
}
int main()
{
    int n,j;
    cin >> n;
    for(int i=0; i<n; i++)
    {
        int temp;
        cin >> temp;
        for(j=1; j<10; j++)
        {
            if((j*temp*temp-temp)%fanhui(temp)==0)
            {

                cout << j << " " << j*temp*temp << endl;
                break;
            }
        }
        if(j==10)
            cout << "No" << endl;

    }
}

解题思路2:

1.to_string是将数字转化为字符串
2.将两个要比较的数字转化为字符串,然后分别计算其长度,然后截取
3.最后比较字符,如果相同则输出

参考代码2:

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

*/
int main() 
{
     int m;
     cin >> m;
     while (m--) 
     {
         int k,n;
         cin >> k;
         for (n = 1; n < 10; n++) 
         {
             int mul = n * k * k;
             string smul = to_string(mul), sk = to_string(k);
             string smulend = smul.substr(smul.length() - sk.length());
             if (smulend == sk) 
             {
                    printf("%d %d\n", n, mul);
                    break;
             }
         }
         if (n==10)
            printf("No\n");
     }
     return 0; 
}

/*

    
*/

知识总结:

1.s.substr(n)表示从s这个字符串中的第n个位置开始截取一直到最后

1092

解题思路:

1.双层for将每次的销售量相加,最后得到一个数组,就下标对应品种,元素值对应总销售量
2.找出其中最大值,然后遍历循环,如果有对应的,则直接按照要求输出输出即可

参考代码:

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

*/
int main()
{
    int n,m;
    cin >> n >> m;
    vector<int> a(n+1);
    for(int i=0; i<m; i++)
    {
        for(int j=1; j<=n; j++)
        {
            int temp;
            cin >>temp;
            a[j]+=temp;
        }
    }
    int max=-1;
    for(int i=1; i<=n; i++)
    {
        if(a[i]>=max)
            max=a[i];
    }
    cout << max << endl;
    int flag=1;
    for(int i=1; i<=n; i++)
    {
        if(a[i]==max)
        {
            if(flag!=1)
                cout << " ";
            cout << i;
            flag++;
        }
    }
}


对以上代码改进:

1.如果将sum设为vector在main函数中就行
2.如果将sum设为普通数组形式,只能将其放到main函数外,否则不正确

参考代码2:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
     int m, n, maxn=0,s;
     cin >> m >> n;
     vector<int> sum(m+1);
     for (int i = 1; i <= n; i++)
     {
         for (int j = 1; j <= m; j++)
         {
             cin >> s;
             sum[j] += s;
             maxn=max(maxn,sum[j]);
         }
     }
     cout << maxn << endl;
     int flag=1;
     for(int i=1; i<=m; i++)
     {
         if(sum[i]==maxn)
         {
              if(flag!=1)
                cout << " ";
             cout << i;
             flag++;
         }

     }
     return 0;
 }


1093

解题思路1:

1.用getline输入两个字符串

2.先相加
3.双层for,从第2开始每次与前面的相比较,如果相同则消除
4.消除2次

参考代码1:

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

*/
int main()
{
    string a,b;
    getline(cin,a);
    getline(cin,b);
    a+=b;
    for(int i=1; i<a.length(); i++)
    {
        for(int j=0; j<i; j++)
        {
            if(a[i]==a[j])
                a.erase(i,1);
        }
    }
    for(int i=1; i<a.length(); i++)
    {
        for(int j=0; j<i; j++)
        {
            if(a[i]==a[j])
                a.erase(i,1);
        }
    }
    cout << a;
}


解题思路2:

1.设置一个数组的初始值全为0
2.以字符串的值作为下标
3.遍历循环字符串,如果字符作为下标所对应的元素值为0,就输出字符;然后在把元素值改为1

参考代码2:

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

*/
int main()
{
     string s1, s2, s;
     int a[150] = {0};
     getline(cin, s1);
     getline(cin, s2);
     s = s1 + s2;
     for (int i = 0; i < s.size(); i++)
     {
         if (a[s[i]] == 0)
            cout << s[i];
         a[s[i]] = 1;
     }
     return 0;
 }

1094

解题思路:

1.每次按照k个连续的数取截取字符串,如果是素数就直接输出,否则最后输出404

参考代码:

#include<iostream>
#include<cmath>
#include<sstream>
using namespace std;
/*

*/
bool fanhui(int a)
{
    for(int i=2; i<sqrt(a); i++)
        if(a%i==0)
            return false;
    return true;
}
int main()
{

    string s;
    int l,k,i;
    cin >> l >> k >> s;
    for(i=0; i<=s.length()-k; i++)
    {
        stringstream ss;
        int a;
        string temp;
        temp=s.substr(i,k);
        ss << temp;
        ss >> a;
        if(fanhui(a))
        {
            cout << a;
            return 0;
        }
    }
    if(i>s.length()-k)
        cout << 404 << endl;
    return 0;
}

以上代码改进:

#include<iostream>
#include<cmath>
using namespace std;
bool fanhui(int a)
{
    if(a==0 || a==1)
        return false;
    for(int i=2; i<sqrt(a); i++)
        if(a%i==0)
            return false;
    return true;
}
int main()
{
    string s;
    int l,k;
    cin >> l >> k >> s;
    for(int i=0; i<=l-k; i++)
    {
        string a=s.substr(i,k);
        int q=stoi(a);  //改进在这里
        if(fanhui(q))
        {
            cout << a;  //注意这里是输出字符串,对于0002,如果输出数字是2,但是题中要求输出0002
            return 0;
        }
    }
    cout << 404 << endl;
    return 0;
}

知识总结:

1.stoi将字符串转化为整数
int q=stoi(a);  //改进在这里

1095

解题思路1:

1.设置结构数组v,输入相关信息
2.for循环嵌套if-else语句:
      1.输入num
      2.根据num不同的值对应不同的操作:
            1.num==1:
                 1.按要求先输出一行
                 2.通过for循环,对应于原结构数组;如果满足条件,则将对应结构压入新的结构数组ans中
                 3.排序+输出
                 4.如果ans的长度为0,则输出NA
            2.num ==2
                 1.设置cnt == o, sum == 0
                 2.按要求输出一行
                 3.通过循环,如果找到对应的考场,则统计人数和总分
                 4.如果人数不为0,则输出人数和总分,否则,输出NA
            3.num ==3
                 1.设置string类型date
                 2.按要求输出一行
                 3.新结构site的数组ans
                  4.通过循环找出,日期对应得,并截取考场字符串,接统计人数
                 5.map中的关键字和元素值对应到结构数组ans中
                  6.排序+输出
                  7.ans长度为0,输出NA

参考代码:

#include <iostream>
#include <vector>
#include <unordered_map>
#include <algorithm>
using namespace std;
struct stu   //准考证和成绩的一个结构
{
     string id;
     int sco;
};

struct site   //考场字符串和人数的一个结构
{
     string siteId;
     int cnt;
};

bool cmp1(const stu a, const stu b)   //如果成绩相同,则按照id的增序输出;否则按照,成绩的降序输出
{
 return a.sco == b.sco ? a.id < b.id : a.sco > b.sco;
}

bool cmp2(const site &a, const site &b)   //如果人数相同,则按照考场字符串的升序输出;否则按照,人数的降序输出
{
 return a.cnt == b.cnt ? a.siteId < b.siteId : a.cnt > b.cnt;
}

int main()
{
     int n, k;
     cin >> n >> k;
     vector<stu> v(n);    //结构数组

     for (int i = 0; i < n; i++)
        cin >> v[i].id >> v[i].sco;  //将信息输入至结构数组

     for (int i = 1; i <= k; i++)
     {
         int num;
         scanf("%d", &num);
         if (num == 1)
         {
             string level;
             cin >> level;   
             printf("Case %d: %d %s\n", i, num, level.c_str());  //level.c_str()专用于printf的输出
             vector<stu> ans;  //定义一个vector的新结构ans
             for (int i = 0; i < n; i++)    //通过for循环,对应于原结构数组;如果满足条件,则将对应结构压入新的结构数组ans中
             {
                 if (v[i].id[0] == level[0])
                    ans.push_back(v[i]);
             }
             sort(ans.begin(), ans.end(),cmp1);  //排序
             for (int i = 0; i < ans.size(); i++)   //输出
             printf("%s %d\n", ans[i].id.c_str(), ans[i].sco);
             if (ans.size() == 0) printf("NA\n");  //如果ans长度为0,则输出NA
         }
         else if (num == 2) 
         {
             int cnt = 0, sum = 0;  //设置cnt=0,sum=0
             int siteId;
             cin >> siteId;   
             printf("Case %d: %d %d\n", i, num, siteId);
             for (int i = 0; i < n; i++)  //通过循环,如果找到对应的考场,则统计人数和总分
             {
                 if (v[i].id.substr(1, 3) == to_string(siteId)) 
                 {
                     cnt++;
                     sum += v[i].sco;
                 }
             }
             if (cnt != 0)    //如果人数不为0,则输出人数和总分
                printf("%d %d\n", cnt, sum);
             else           //否则,输出NA
                printf("NA\n");
         } 
         else if (num == 3) 
         {
             string date;
             cin >> date;
             printf("Case %d: %d %s\n", i, num, date.c_str());
             vector<site> ans;     //新结构site的数组ans
             unordered_map<string, int> m;
             for (int i = 0; i < n; i++)   //通过循环找出,日期对应得,并截取考场字符串,接统计人数
             {
                 if (v[i].id.substr(4, 6) == date) 
                 {
                     string tt = v[i].id.substr(1, 3);
                     m[tt]++;
                 }
             }
             for (auto it : m)  //将map中的关键字和元素值对应到结构数组ans中
                ans.push_back({it.first, it.second});
             sort(ans.begin(), ans.end(),cmp2);
             for (int i = 0; i < ans.size(); i++)
                printf("%s %d\n", ans[i].siteId.c_str(), ans[i].cnt);
             if (ans.size() == 0) 
                    printf("NA\n");
         }
     }
     return 0;
 }

知识总结:

1.用printf输出string类型字符串
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
    string s;
    cin >> s;
    printf("%s\n",s);     //string类型的变量如果用printf输出,就不对
    printf("%s",s.c_str());  //对于printf,只能用c_str()*/
}

2.c++11新特性,直接输出v的字符串
#include<iostream>
#include<string>
#include<vector>
using namespace std;
int main()
{
    vector<int> v={1,2,3,4};
    for(auto i:v)
        cout << i;

}

3.c++11新特性,将map的关键字和元素值对应到结构数组中
#include<iostream>
#include<string>
#include<vector>
#include<unordered_map>
using namespace std;
struct site   //考场字符串和人数的一个结构
{
     string siteId;
     int cnt;
};  
int main()
{ 
    vector<site> ans;
    unordered_map<string, int> m;    
    for (auto it : m)
        ans.push_back({it.first, it.second});

}

4.map和unordered_map的区别:

map:

优点:

有序性,这是map结构最大的优点,其元素的有序性在很多应用中都会简化很多的操作
红黑树,内部实现一个红黑书使得map的很多操作在lgn的时间复杂度下就可以实现,因此效率非常的高
缺点: 空间占用率高,因为map内部实现了红黑树,虽然提高了运行效率,但是因为每一个节点都需要额外保存父节点、孩子节点和红/黑性质,使得每一个节点都占用大量的空间

适用处:对于那些有顺序要求的问题,用map会更高效一些

unordered_map:

优点: 因为内部实现了哈希表,因此其查找速度非常的快
缺点: 哈希表的建立比较耗费时间
适用处:对于查找问题,unordered_map会更加高效一些,因此遇到查找问题,常会考虑一下用unordered_map
总结:

内存占有率的问题就转化成红黑树 VS hash表 , 还是unorder_map占用的内存要高。
但是unordered_map执行效率要比map高很多
对于unordered_map或unordered_set容器,其遍历顺序与创建该容器时输入的顺序不一定相同,因为遍历是按照哈希表从前往后依次遍历的

注意事项:

  1.         printf("Case %d: %d %s\n", i, num, level.c_str());  //level.c_str()专用于printf的%s输出
    
printf("%s %d\n",ans[i].id.c_str(),ans[i].sco)向比于cout << ans[i].id << " " << ans[i].sco << endl节省时间
printf("%s %d\n",ans[k].siteId.c_str(),ans[k].cnt)相比于cout << ans[k].siteId << " " << ans[k].cnt << endl;节省时间
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值