PAT甲级真题

 

A042[Shuffling Machine] 简单模拟

输入洗牌次数K,换行输入给定的交换顺序,要求顺序输出洗K次后的牌号。

[思路]

一共有54张牌,一共5个花色S,H,C,D,J,每种花色有13张。

用1~13表示花色S,用14~26表示花色H,用27~39表示花色C,用40~52表示花色D,用53和54表示花色J。

创立一个字符数组mp[ ]存放花色SHCDJ。

创立三个数组start[ ],next[ ]和end[ ]。用for循环将1到54输入start[ ]的start[1]到start[54],接着用scanf接收给定的交换顺序到数组next[1]到next[54],再接用for的嵌套进行K次洗牌,使用语句end[next[i]]=start[i]按洗后的牌序给到end数组,并且每一次洗好后都将end[ ]覆盖再start[ ]上。

换洗结束,将牌面用for循环将start[]数组内容打印出来。注意格式,每输出一个后面要加空格。注意内容为1~13的需要用到mp[0]中的S,14~26需要换算成1~13,所以要使用语句:

start[i]--;

ptintf("%c%d",[mp[start[i]/13];star[i]%13+1);

[注意]for嵌套循环里的两个for

#include <cstdio>
using namespace std;
int main()
{
	char mp[5] = { 'S','H','C','D','J' };
	int N = 54;
	int K;
	int start[55];
	int next[55];
	int end[55];
	scanf("%d", &K);
	for (int i = 1; i < 55; i++)
	{
		start[i] = i;
	}
	for (int i = 1; i < 55; i++)
	{
		scanf("%d", &next[i]);
	}
	for (int step = 0; step < K; step++) {
		for (int i = 1; i < 55; i++) {
			end[next[i]] = start[i];
		}
		for (int i = 1; i < 55; i++) {
			start[i] = end[i];

		}
	}
	for (int i = 1; i < 55; i++)
	{
		if (i != 1)printf(" ");
		start[i]--;
	printf("%c%d", mp[start[i] / 13],start[i] % 13 + 1);
	}
	return 0;
}

A1025[PAT Ranking]排序

有N个考场,每个考场里有K个学生。现给出考场内每个考生的准考证号和分数,要求按最终排名递增的方式输出

准考证号 最终排名 考场号 考场排名     如果二者同分,则按照二者准考证号递增的方式输出

[思路]

步骤一.定义一个student结构体,然后用嵌套for循环将每个考场的考生信息录入,并将每个考场里的考生排名进行排序,录入结构体当中,便于最后输出local_rank。

步骤二.对所有考生排名进行一个排序,边排序边输出考生的信息。分数相同的令其排名等于前一个考生的排民,分数不同的则排名为人数+1。(以下为该方法实现的代码)

r=1;

for(i=0;i<num;i++){

if(i>0&&stu[i].score!==stu[i-1].score){

r=i+1;}

else printf(   )

}

[该题整体代码]start--代替了start[i]-1

#include <cstdio>

#include <cstring>

#include <algorithm>

using namespace std;

struct Student {

	char id[20];

	int score;

	int location_number;

	int local_rank;

}stu[30090];

bool cmp(Student a, Student b) {
	if (a.score != b.score)return a.score > b.score;
	else return strcmp(a.id, b.id) < 0;
}
int main()
{
	int n,k,num = 0;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &k);
		for (int j = 0; j < k; j++) {
			scanf("%s %d",stu[num].id,&stu[num].score);//这里记得写数组大小30090
			stu[num].location_number = i;//该语句用以记录每个考生的考场号,最后需要输出。
			num++;//num变量的作用是记录总人数,以便最后用for循环将所有考生成绩进行排名。
		}
		sort(stu + num - k, stu + num, cmp);
		stu[num-k].local_rank = 1;
		for (int j = num - k + 1; j < num; j++) {
			if (stu[j].score != stu[j - 1].score) { stu[j].local_rank = j + 1 - (num - k); }
			else{stu[j].local_rank = stu[j - 1].local_rank; }

		}//该for循环用以将每个考场内的考生loacl_rank记录下来,用以最后的输出。
	}
	printf("%d\n", num);
	sort(stu, stu + num, cmp);
	int r = 1;
	for (int i = 0; i < num; i++)
	{
		if (stu[i].score != stu[i - 1].score)r = i + 1;
		printf("%s %d %d %d\n", stu[i].id, r, stu[i].location_number, stu[i].local_rank);

	}
	return 0;

}

A1046[Shortest Distance]简单模拟

给出不大于100000个的点,以及第一个到第二个点...第N个到第一个点的N个距离,换行给出不大于M的询问,接着M行写出要求的两个点,要求逐行输出询问的M个最短距离。

[思路]用数组A[]存放第一行输入的相邻的距离,dis[i]数组用于存放第1行到第i行的顺时针下一个结点的距离,用sum来存放总距离,在用for循环输入第一行的同时预处理dis[]数组和sun变量。再定义left和right两个变量存放询问中的结点,最后用

dis[right-1]-dis[left-1]求得顺时针到达的距离,再用min()函数求出顺逆中最短的那个距离。

[注意]

如果left<right,使用swap()交换。

#include <cstdio>
#include <algorithm>
using namespace std;
int A[100010], dis[100010];
int main(){
	int n, m,left,right,sum = 0;
	scanf("%d", &n);
	for (int i = 1; i <= n; i++) {
		scanf("%d", &A[i],100010);
		sum += A[i];
		dis[i] = sum;
	}
	scanf("%d",&m);
	for (int i=1;i<=m;i++)
	{
		scanf("%d%d", &left, &right);
		if (left > right)swap(left, right);
		int temp = dis[right - 1] - dis[left - 1];
		printf("%d\n", min(temp, sum - temp));


	}
	return 0;
}

A1002[A+BforPolynomial]简单模拟

给出两行,每行表示一个多项式:第一个数字表示多项式中系数非零的项,后面每两个数表示一个项,这两个数分别表示该该项的幂次和系数,要求输出两个多项式之和,并且以前面的输入的格式来输出。

#include <cstdio>
	double ans[1006];//存放结果多项式
	double A[1005];
	double B[1005];//存放A的指数和系数
	int main(){
		int n, m,k;
        double a;
	
		scanf("%d", &k);//第一个多项式的项数
		for (int i = 0; i < k; i++) {
			scanf("%d %lf",&n,&a);
			A[n] = a;
		}
		scanf("%d", &k);//第二个多项式的项数
		for(int i = 0; i < k; i++) {
			scanf("%d %lf", &m, &a);
			B[m] = a;
		}
		for (int i = 0; i < 1005; i++) {
			ans[i] = A[i] + B[i];
		}
		int count=0;
		for(int i = 0; i < 1006; i++) {
			if (ans[i] != 0)count++;
		}
		printf("%d",count);
		for(int i = 1005; i>=0;i--) {
			if (ans[i] != 0) { printf(" %d %.1f", i, ans[i]); }

		}
		return 0;

}

 

A1009[Product of Polynomias]简单模拟

给出两行,每行表示一个多项式:第一个数字表示多项式中系数非零的项,后面每两个数表示一个项,这两个数分别表示该该项的幂次和系数,要求输出两个多项式之乘积,并且以前面的输入的格式来输出。

[注意]一定一定要注意输出的格式,题目提及accurate to 1 decimal place则是要求精准到一位小数,还有一定一定要注意不可以在输出末尾多出一个空格来。注意数组大小为2016时,数组最大下标为2015,在for循环里需要注意。

#include <cstdio>
	double ans[2015];//存放结果多项式
	double A[1005];
	double B[1005];//存放A的指数和系数
	int main(){
	int n, m, zhi, ZHI;
		double xi,XI;
		scanf("%d", &n);//第一个多项式的项数
		for (int i = 0; i < n; i++) {
			scanf("%d %lf",&zhi,&xi);
			A[zhi] = xi;
		}
		scanf("%d", &m);//第二个多项式的项数
		for(int i = 0; i < m; i++) {
			scanf("%d %lf", &ZHI, &XI);
			B[ZHI] = XI;
		}
		for(int i = 0; i < 1005; i++)
			for (int j = 0; j <1005; j++)
				ans[j+i]+=(B[j] * A[i]);
		int count = 0;
		for(int i = 0; i < 2015; i++) {
			if (ans[i] != 0.0)count++;
		}
		printf("%d",count);
		for(int i = 2014; i>=0;i--) {
			if (ans[i] != 0.0) { printf(" %d %.1f", i, ans[i]); }//注意此处必须前面放空格因为不能有额外的空格

		}
		return 0;

}

A1006[Sign in and Sign out]简单查询

[注意]比较函数great的写法,scanf输入字符串%s给到数组temp.id,前面无需写取址符号&。要注意比较函数great输出false和true代表着什么。

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
struct pNode{
    char id[20];
    int hh,mm,ss;
}ans1,ans2,temp;

    bool great(pNode a,pNode b){
        if(a.hh!=b.hh)return a.hh>b.hh;
        if(a.mm!=b.mm)return a.mm>b.mm;
        return a.ss>b.ss;}//比较函数要写在主函数的前面
int main(){
    int m;
    ans1.hh=24,ans1.mm=60,ans1.ss=60;//把ans1设为最大以便比较替换
    ans2.hh=0,ans2.mm=0,ans2.ss=0;//把ans2设为最小以便替换
    scanf("%d",&m);
    for(int i=0;i<m;i++){
        scanf("%s %d:%d:%d",temp.id,&temp.hh,&temp.mm,&temp.ss);//注意scanf给到数组的时候前面不用加&号,注意此处的%s传给数组这个操作
        if(great(temp,ans1)==false)ans1=temp;//ans小于temp则将ans更新
        scanf("%d:%d:%d",&temp.hh,&temp.mm,&temp.ss);
        if(great(temp,ans2)==true)ans2=temp;
    }
    printf("%s %s\n",ans1.id,ans2.id);
    return 0;
    }

 

A1036[boys vs girls]简单查询

结构体struct 的运用,temp作为中间结构体变量和对需要输出的结构体变量M,F进行初始化以便后面的覆盖,这两点与上一题相似。

 

#include <cstdio>
struct person {
	char name[15];
	char id[15];
	int score;
	char sex;
}M, F, temp;//因为题目要求输出,temp为中间变量


int main() {
	M.score = 101;
	F.score = -1;
	int k;
	char sex;
	scanf("%d", &k);
	for (int i = 0; i < k; i++) {
		scanf("%s %c %s %d", temp.name, &temp.sex, temp.id, &temp.score);
		if (temp.sex == 'M'&&temp.score < M.score) { M = temp; }//注意是把整个temp变量赋给M,把整个M更新
		else if (temp.sex == 'F'&&temp.score > F.score) { F = temp; }
	}
	if (F.score == -1)printf("Absent\n");
	else printf("%s %s\n", F.name, F.id);
	if (M.score == 101)printf("Absent\n");
	else printf("%s %s\n", M.name, M.id);
	if (F.score == -1 || M.score == 101)printf("NA\n"); else printf("%d", F.score - M.score);
	return 0;
}

A1031[hello world for u]图形输出

[思路]弄清各列的关系,可以列举5个来看其中的规律。然后用表达式表示各列有多少个字符需要打印,然后for循环逐行打印

【注意】在输出的时候要记得是逐行输出的,因此要要注意for循环里的条件,还有输出的格式。用scanf给到str时不用&取地址符也不用写str[100]后面[100]。

#include <cstdio>
#include <cstring>
int main(){
    char str[100];
    int N,n1,n2,n3;
    scanf("%s",str);
    N=strlen(str);//获取字符串长度
    n1=(N+2)/3;
    n3=n1;
    n2=N+2-n1-n3;
    for(int i=0;i<n1-1;i++){//先输出n1-1行
        printf("%c",str[i]);//输出当前左侧的字符
        for(int j=0;j<n2-2;j++){
            printf(" ");
        }
        printf("%c\n",str[N-i-1]);//记住每打完一行要换行,一直卡在这里
    }
    for(int i=0;i<n2;i++){
        printf("%c",str[n1+i-1]);//不用\n换行
    }
    return 0;

}

A1019[General Palindromic Number]进制处理

[思路]十进制decimal转换成别的j模板

[注意]定义函数的bool judge(int z[],int num){},调用函数的时候就bool ans=judge(z,num);

int z[40],num=0;
do{
z[num++]=n%b;
n=n/b;
}while(n!=0);//n为需要转换的数字,b为转换后的进制。
#include <cstdio>
bool judge(int z[],int num){
    for(int i=0;i<num/2;i++){
        if(z[i]!=z[num-1-i])return false;
    }
    return true;
}//注意此处的true和false不可以调换顺序,自己思考一下
int main(){
    int n,b,num=0;//num用于存放位数
    int z[100];
    scanf("%d %d",&n,&b);
    do{
        z[num++]=n%b;
        n=n/b;

    }while(n!=0);//此处用do...while...记得最后的分号,由于边界数据0所以采用先执行后判断的语句。
bool ans=judge(z,num);//此处的z不用加数组大小,也不用前面的int
if(ans==true)printf("Yes\n");
else printf("No\n");
for(int i=num-1;i>=0;i--){
    printf("%d",z[i]);
    if(i!=0)printf(" ");
}

return 0;

}

 

A1027

#include <cstdio>
int main(){
    char haha[14]={'0','1','2','3','4','5','6','7','8','9','A','B','C'};
    int a,b,c;
    printf("#");
    scanf("%d%d%d",&a,&b,&c);
    printf("%c%c",haha[a/13],haha[a%13]);
     printf("%c%c",haha[b/13],haha[b%13]);
      printf("%c%c",haha[c/13],haha[c%13]);
      return 0;
}

A1058[A+B in hogwarts]进制转换

[注意]一定要设立一个j用来存放进位,不然后面在处理c[]数组的时候会答案错误。

#include <cstdio>
int main(){
    int a[3],b[3],c[3];
    int j;//用于存放j进位
    scanf("%d.%d.%d %d.%d.%d",&a[0],&a[1],&a[2],&b[0],&b[1],&b[2]);
    for(int i=0;i<=2;i++){
        c[i]=a[i]+b[i];
    }   
        j=c[2]/29;
        c[2]=c[2]%29;
     c[1]=c[1]+j;
        j=c[1]/17;
c[1]=c[1]%17;
        c[0]=c[0]+j;
    
    printf("%d.%d.%d",c[0],c[1],c[2]);
    return 0;
}

A061[dating]日期处理

#include <cstdio>
#include <cstring>
int main(){
    char day[8][5]={"MON","TUE","WED","THU","FRI","SAT","SUN"};
    char str1[65],str2[65],str3[65],str4[65];
scanf("%s %s %s %s",str1,str2,str3,str4);
    int len1=strlen(str1);
    int len2=strlen(str2);
    int len3=strlen(str3);
    int len4=strlen(str4);
    int i;
    for(i=0;i<len1&&i<len2;i++){
        if(str1[i]==str2[i]&&str1[i]<='G'&&str1[i]>='A'){
            printf("%s ",day[str1[i]-'A']);
            break;//让day[]内变为整数所以-'A',记住要加break不然会一直x找下去
        }
    }
    for(i++;i<len1&&i<len2;i++){
        if(str1[i]==str2[i]){
            if(str1[i]>='0'&&str1[i]<='9'){printf("%02d:",str1[i]-'0');break;}
            else if(str1[i]>='A'&&str1[i]<='N'){printf("%d:",str1[i]-'A'+10);break;}
    }
    }
    for(i=0;i<len3&&i<len4;i++){
        if(str3[i]==str4[i]){
            if((str3[i]>='a'&&str3[i]<='z')||(str3[i]>='A'&&str3[i]<='Z')){printf("%02d",i);break;}//输出,数据不到2位左边补0
        }
    }


    return 0;
}














    
    

A1071[科学计数法]字符串处理

[注意]

1.如果字符串中含有数字然后需要转换成int型的话,就用exp=str[i]-'0'的方法来转换。

2.有极端状况就是指数为0

3.指数为正数的时候要分两种情况:1.指数小于原小数点右边的位数,在exp+2的位置要加上小数点

4.指数大于原小数右边的位数,要记得多输出exp-(pos-3)个零。

5.如果是在一段数组里找到某个什么就停止,用for循环的时候要记得加break

#include <cstdio>
#include <cstring>
int main(){
    char str[100010];
    scanf("%s",str);
    if(str[0]=='-')printf("-");
    int pos=0;//存放pos的位置
    int exp=0;//存放指数d
    int length=strlen(str);
while(str[pos]!='E'){pos++;}//此处不可以用for循环,因为不知道pos的位置,自己体会
    //pos用于记录E的位置
    for(int i=pos+2;i<length;i++){
exp=exp*10+(str[i]-'0');
    }//exp用于记录指数,接下来分指数为正和负的情况来输出
     if(exp==0){for(int i=1;i<pos;i++){printf("%c",str[i]);}}//极端情况指数为零


if(str[pos+1]=='-'){
    printf("0.");
    for(int i=0;i<exp-1;i++){//i此处exp-1
        printf("0");
    }
  printf("%c",str[1]);
  for(int i=3;i<pos;i++)printf("%c",str[i]);
}
else{
    for(int i=1;i<pos;i++){//输出符号和E中间a那些非小数点的数字
        if(str[i]=='.')continue;//遇到小数点跳出循环继续执行循环,break是终止循环
        printf("%c",str[i]);
        if(i==exp+2&&pos-3!=exp)printf(".");//小数点要加在exp+2的位置上,原小数点和E之间的个数不能等于指数
        }
        for(int i=0;i<exp-(pos-3);i++){printf("0");}

}
return 0;
}

A1001[A+B for Format]进制转换

#include <cstdio>
int main(){
    int a,b,sum;
    scanf("%d %d",&a,&b);
    sum=a+b;
    if(sum<0){printf("-");sum=-sum;}
    if(sum<1000)printf("%d",sum);
    else if(sum<1000000)printf("%d,%03d",sum/1000,sum%1000);
    else printf("%d,%03d,%03d",sum/1000000,sum%1000000/1000,sum%1000);
    
    

return 0;
        
    }

A1005[Spell It Right]字符串处理

[注意]sprintf(ans,"%d",sum)为转换格式的简便方法,就是把整形的sum转换为字符串的形式存放在ans[]数组里

#include <cstdio>
#include <cstring>
int main(){
    char a[15][15]={"zero","one","two","three","four","five","six","seven","eight","nine"};
    char z[110];//存放输入的字符串
    char ans[4];
    scanf("%s",z);
    int len1=strlen(z);//len存放字符串的长度
    int sum=0;
    for(int i=0;i<len1;i++){
        sum=sum+(z[i]-'0');//求出各数位之和
    }
    sprintf(ans,"%d",sum);//转换格式
    int len2=strlen(ans);
    for(int i=0;i<len2;i++){
        printf("%s",a[ans[i]-'0']);//注意此处一定要-'0'
        if(i!=len2-1)printf(" ");
    }
    return 0;



}

A1077[Kuchiguse]字符串处理

[注意]

1.

二维数组的读入c.getline(数组名,数组大小)如c.getline(str[i],256),如果输入256个字符,读取255个

一维数组的读入c.getline(数组名,数组大小) 如:c.getline(a,10),如果输入10个字符,读取9个 

 

需要头文件#include <cstring> #include<iostream> using namespace std;

此函数一次读取多个字符(包括空白字符),直到读满N-1个,或者遇到指定的结束符为止(默认的是以'\n'结束)
#include<iostream>
using namespace std;
int main()
{char a[10];cin.getline(a,10);for(int i=0;i<10;i++)cout<<a[i]<<" ";return 0;
}
输入:1234567890123
输出:1 2 3 4 5 6 7 8 9 _ (第10位存放字符串结束符'\0')


2.如果字符串中有空格的话不要用scanf读入,因为scanf的%s是以空白(包括空格)来截断的。

3.在读入整数N后要用getchar()来吸收换行符,才不会让后面的字符串读入出现错误。

 

A[1082]Read Number in Chinese

[思路]8008 ,8080,

1.将数字分为个节万节亿节,用left指示字符串的当前输出的位,right指向与left同一节的个位。

2.注意0额外的0的输出

3.bool型变量isprint 和 flag分别用来指示一节是否有输出和是否有积累的0

 

#include <cstdio>
#include <cstring>
char num[10][5]={"ling","yi","er","san","si","wu","liu","qi","ba","jiu"};
char wei[5][5]={"Shi","Bai","Qian","Wan","Yi"};
int main(){
    char str[15];
    scanf("%s",str);
    int len=strlen(str);
    int left=0,right=len-1;
    if(str[0]=='-'){
        printf("Fu");
        left++;
    }

    while(left+4<=right){
        right-=4;
    }//将right不停左移四节直到left与right在同一节

    while(left<len){
        bool flag=false;//flag==false表示没有积累的0
        bool isprint=false;//isprint==false表示该节没有输出过其中的位
        while(left<=right){//从左至右处理数字某节中的每一位
        if(left>0&&str[left]=='0'){//如果当前位为0
        flag=true;

        }else{//当前位不为0
            if(flag==true){//存在积累的0
                printf(" ling");
                flag=false;
            }
            //只要不是首位(包括负号),后面的每一位前都要输出空格
            if(left>0)printf(" ");
            printf("%s",num[str[left]-'0']);//输出当前数字
            isprint=true;//该节至少有一位被输出
            if(left!=right){
                printf(" %s",wei[right-left-1]);//除个位外都需要输出十百千
            }
        }
        left++;

        }
        if(isprint==true&&right!=len-1){//只要不是个位并且中间不是4个零就输出万或亿,注意100000008
            printf(" %s",wei[(len-1-right)/4+2]);
        }
        right+=4;//right右移4位,输出下一节

    }
    return 0;
}

 

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值