PAT (Basic Level) 1041-1050

目录

1041 考试座位号

1042 字符统计

1043 输出PATest

1044 火星数字

1045 快速排序

1046 划拳

1047 编程团体赛

1048 数字加密

1049 数列的片段和

1050 螺旋矩阵


1041 考试座位号

用以试机号码为下标,以准考证与考试座位号码组成的结构体为值的map进行存储。

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

struct inf
{
    string number;
    int seat;
};

int main()
{
    int n;
    cin>>n;
    map<int,inf> stu;
    
    while(n--)
    {
        string s;
        int a,b;
        cin>>s>>a>>b;
        stu[a]={s,b};
    }
    
    int m;
    cin>>m;
    while(m--)
    {
        int c;
        cin>>c;
        cout<<stu[c].number<<" "<<stu[c].seat<<"\n";
    }
}

1042 字符统计

(1)要注意输入的时候不要用cin,因为是一整行的输入;

(2)19、20行的判定不可以缺少,不然测试点1会出错。

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

int main()
{
    string s;
    getline(cin,s);//一整行,不要用cin
    int a[128]={0};
    for(int i=0;i<s.length();i++)
    {
        s[i]=tolower(s[i]);
        a[s[i]]++;
    }
    
    int max=0,index=0;
    for(int i=65;i<123;i++)
    {
        if(!isalpha(i))
            continue;
        if(a[i]>max)
        {
            max=a[i];
            index=i;
        }
    }
    printf("%c %d",index,max);
}

1043 输出PATest

普通的散列表题目。

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

int main()
{
    string s;
    cin>>s;
    map<char,int> m;
    
    for(auto x:s)
        if(x=='P'||x=='A'||x=='T'||x=='e'||x=='s'||x=='t')
            m[x]++;
    
    while(m['P']>0||m['A']>0||m['T']>0||m['e']>0||m['s']>0||m['t']>0)
    {
        if(m['P']>0)
        {
            cout<<"P";
            m['P']--;
        }
        if(m['A']>0)
        {
            cout<<"A";
            m['A']--;
        }
        if(m['T']>0)
        {
            cout<<"T";
            m['T']--;
        }
        if(m['e']>0)
        {
            cout<<"e";
            m['e']--;
        }
        if(m['s']>0)
        {
            cout<<"s";
            m['s']--;
        }
        if(m['t']>0)
        {
            cout<<"t";
            m['t']--;
        }
    }
}


1044 火星数字

(1)要理解题意,首先tret只与0对应,比如13只是tam而不是tam tret,与常见十进制有区别;

(2)16行的问题在前面的题目里提到很多次,有分隔一起读取不要用cin;

(3)在火星文转数字的情况下,用字符串长度来区分只有低位、高低位、0的情况(只有0一个四位);

(4)参考其他博主的题解,高位数组第一位为空串,因为不会使用到它而这样其他情况的high数组下标对应更方便。

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

int main()
{
    string low[13]={"tret","jan","feb","mar","apr","may","jun","jly","aug","sep","oct","nov","dec"};
    string high[13]={"","tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"};
    int n;
    cin>>n;
    char c=getchar();
    
    while(n--)
    {
        string s;
        getline(cin,s);//因为要输入一整行,不要用cin,不然大于13的大小为7的火星文会出错
        if(isdigit(s[0]))//首位是数字,转火星文
        {
            int num=stoi(s);
            if(num<13)
                cout<<low[num]<<endl;
            else if(num%13==0)
                cout<<high[num/13]<<endl;
            else
                cout<<high[num/13]<<" "<<low[num%13]<<endl;
            
        }
        else//转数字
        {
            if(s.size()==3)
            {
                for(int i=0;i<13;i++)
                    if(low[i]==s)
                        cout<<i<<endl;
                for(int i=0;i<13;i++)
                    if(high[i]==s)
                        cout<<i*13<<endl;
            }
            
            if(s.size()==4)
                cout<<0<<endl;
            if(s.size()==7)
            {
                int num1=0,num2=0;
                string s1=s.substr(0,3);
                string s2=s.substr(4,3);
                for(int i=0;i<13;i++)
                    if(s1==high[i])
                        num1=i;
                for(int i=0;i<13;i++)
                    if(s2==low[i])
                        num2=i;
                
                cout<<num1*13+num2<<endl;
            }
        }
    }
}

1045 快速排序

(1)思路是将原序列与经过排序的序列比较,因为主元在两个序列中的位置必然是相同的,但一个限制条件不够,因为若原序列是倒序排列,那么其中位数与排序后的中位数也同位置但不是主元所以加上第二个条件:比前面所有元素大;

(2)用<algorithm>的sort()函数排序,如果手写一个快排比较时间复杂度就是O(nlgn),会超时;

(3)如果不对无主元即容器result为空的情况下,单独讨论情况,输出两个换行符,会导致测试点2的格式错误;

(4)第10行定义容器v1v2时,若不给定大小为你,会导致段错误。

#include<iostream>
#include<vector>
#include<algorithm>
using namespace std;

int main()
{
    int n;
    cin>>n;
    vector<int> v1(n),v2(n);
    vector<int > result;
    
    for(int i=0;i<n;i++)
    {
        cin>>v1[i];
        v2[i]=v1[i];
    }
    sort(v1.begin(),v1.end());
    
    int max=0;
    for(int i=0;i<n;i++)
    {
        if(v1[i]==v2[i]&&v2[i]>max)
            result.push_back(v2[i]);
        if(v2[i]>max)
            max=v2[i];
    }
    
    //output
    cout<<result.size()<<endl;
    if(result.size()==0)
        cout<<endl;
    else
        for(int i=0;i<result.size();i++)
        {
            if(i==0)
                cout<<result[0];
            else
                cout<<" "<<result[i];
        }
}

1046 划拳

水题。

#include<iostream>
using namespace std;

int main()
{
    int n,sumA=0,sumB=0;
    cin>>n;
    while(n--)
    {
        int a,b,c,d;
        cin>>a>>b>>c>>d;
        if(b==a+c&&d==a+c)
            continue;
        if(b==a+c)
            sumB++;
        if(d==a+c)
            sumA++;
    }
    cout<<sumA<<" "<<sumB;
}

1047 编程团体赛

水题,队员号不需要考虑。

#include<iostream>
using namespace std;

int main()
{
    int n;
    cin>>n;
    int s[10005]={0};
    while(n--)
    {
        int team,a,score;
        scanf("%d-%d %d",&team,&a,&score);
        s[team]+=score;
    }
    
    int maxTeam=0,maxScore=0;
    for(int i=0;i<10005;i++)
    {
        if(s[i]>maxScore)
        {
            maxScore=s[i];
            maxTeam=i;
        }
    }
    cout<<maxTeam<<" "<<maxScore;
}

1048 数字加密

(1)注意因为字符串从0开始作下标记位,所以奇偶位的判定是跟i的奇偶有差别的;

(2)在对字符串操作之前先补前置0使位数相同。

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

int main()
{
    string s1,s2;
    string s3="";
    cin>>s1>>s2;
    int len=max(s1.length(),s2.length());
    if(s1.length()<s2.length())
		s1.insert(0,len-s1.length(),'0');
	else if(s1.length()>s2.length())
		s2.insert(0,len-s2.length(),'0');
    reverse(s1.begin(),s1.end());
    reverse(s2.begin(),s2.end());
    
    for(int i=0;i<len;i++)
    {
        if(i%2==0)//奇数位
        {
            int odd=((s1[i]-'0')+(s2[i]-'0'))%13;
            if(odd==10)
                s3+='J';
            else if(odd==11)
                s3+='Q';
            else if(odd==12)
                s3+='K';
            else
                s3+=to_string(odd);
        }
        else//偶数位
        {
            int even=((s2[i]-'0')-(s1[i]-'0'));
            while(even<0)
                even+=10;
            s3+=to_string(even);
        }
    }
    
    reverse(s3.begin(),s3.end());
    cout<<s3;
}

1049 数列的片段和

用浮点型变量进行大量数据运算时,可能会出现误差,因此这里参考这位博主的题解,先乘1000再除1000输出。

#include<iostream>
using namespace std;
int main()
{
	int n;
    cin>>n;
	double a[100005]={0};//储存数字,是double
	long long b[100005]={0};//储存数字出现的次数,需要开long long。当n的数值过大时,int会数值溢出。
	for(int i=0;i<n;i++)
	    cin>>a[i];
    
	b[0]=n;
	long long temp=n-1;
	long long t= n-1;
	for(int i=1;i<n;i++)//计算每个数字出现的次数,将次数储存在b[i]里。
	{
		b[i]+=n-i;
		b[i]+=temp;
		t--;
		temp = t*(i+1);
	}
    
	long long sum=0;
	for(int i=0;i<n;i++)
		sum+=(long long)(1000*a[i])*b[i];
	printf("%.2lf",sum/1000.0);
}

1050 螺旋矩阵

(1)对于如何求得满足题设的m、n,在12行的for循环中实现,采用了将较小的n从N平方根递降找到第一个N因子,即找到N的因子中较小那一半中最大的作为n,再相除得m;

(2)初始化二维数组时,应如此定义:

vector<vector<int>> b(m,vector<int>(n));

 但若如此定义就会出现段错误:

vector< vector<int> > b(m);
	for(int i=0;i<m;i++)
	    b[i].resize(n); 

首先出错代码中,resize()可以传递两个参数,分别是大小和初始值,初始值默认为0,具体相关用法可以参考这篇

然后关于这里vector的初始化可以参考这篇中的方法六;

(3)关于最难的部分,即27到67行的螺旋填充:

拐几次弯回到原来的模式,就用几层循环,这里举行四条边用了4层内循环,顺时针填充每一条边,用round记录圈数,每次循环后判断count,小于0就跳出。

#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
using namespace std;

int main(){
    int N;
    cin>>N;
    int m,n;
    
    for(n=sqrt(N);n>=1;n--)
    {
        if(N%n==0)
        {
            m=N/n;
            break;
        }
    }

    vector<int> a(N);
    for(int i=0; i<N; i++)
        cin>>a[i];
    sort(a.begin(), a.end());// 升序
    vector<vector<int>> b(m,vector<int>(n));

    int count=N-1;//记录是否用完
    int round=0;//第几圈
    int i=0;//行数
    int j=0;//列数
    while(1)
    {
        for (j=round; j<n-round; j++)
        {
            b[i][j]=a[count];
            count--;
        }
        if(count<0)
            break;
        j--;
        
        for (i=round+1;i<m-round;i++)
        {
            b[i][j]=a[count];
            count--;
        }
        if(count<0)
            break;
        i--;
        
        for (j=n-round-2;j>=round;j--)
        {
            b[i][j]=a[count];
            count--;
        }
        if(count<0)
            break;
        j++;
        
        for (i=m-round-2;i>round;i--)
        {
            b[i][j]=a[count];
            count--;
        }
        if(count<0)
            break;
        i++;
        
        round++;
    }

    //打印矩阵
    for (int i=0;i<m;i++)
    {
        cout<<b[i][0];
        for(int j=1;j<n;j++)
            cout<<" "<<b[i][j];
        cout << endl;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值