PAT乙级考前总结(二)

时间:2021-04-17 15:49:52

简单模拟

1002 写出这个数 (20 分)

1006 换个格式输出整数 (15 分)

又是数数

1016 部分A+B 15 分)

相当于找数字

1018 锤子剪刀布 (20 分)

题目略

此处用了书上的做法,感觉处理起来比较清晰

#include <cstdio>

using namespace std;

int change(char c)//将字符转化成数字便于处理

{

  if(c=='B') return 0;

  if(c=='C') return 1;

  if(c=='J') return 2;

}

int main()

{

char mp[3]={'B','C','J'};

int n;

scanf("%d",&n);

int timesA[3]={0},timesB[3]={0};//存胜,平,负的次数

int handA[3]={0},handB[3]={0};//存每种手势胜的次数

char c1,c2;

int k1,k2;

for(int i=0;i<n;++i)

{

getchar();//去换行

scanf("%c %c",&c1,&c2);

k1=change(c1);k2=change(c2);

if((k1+1)%3==k2)//

{

timesA[0]++;timesB[2]++;handA[k1]++;

}else if(k1==k2)//

{

timesA[1]++;timesB[1]++;

}else//

{

timesA[2]++;timesB[0]++;handB[k2]++;

}

}

printf("%d %d %d\n",timesA[0],timesA[1],timesA[2]);

printf("%d %d %d\n",timesB[0],timesB[1],timesB[2]);

int id1=0,id2=0;

for(int i=0;i<3;i++)

{

if(handA[i]>handA[id1]) id1=i;

if(handB[i]>handB[id2]) id2=i;

}

printf("%c %c\n",mp[id1],mp[id2]);

return 0;

}

1026 程序运行时间 (15 分)

题目说了一大堆,最后就是四舍五入转化一下。

1028 人口普查 (20 分)

题略,大概就是在规定的范围内找最老和最年轻的

#include <stdio.h>

#include <iostream>

using namespace std;

 

const int MAX =100010;

struct id{

  char name[6];

  int data;

} people[MAX];//定义结构

int old=18140906;//最老的界限

int young=20140906;//最年轻的界限

int main()

{

  int n,year,month,day,s=0,max,min,youngest,oldest;

  max=young+1;//可取的最大值

  min=old-1;//可取的最小值

  scanf("%d",&n);

  for(int i=0;i<n;++i)

  {

    scanf("%s %d/%d/%d",people[i].name,&year,&month,&day);

    people[i].data=10000*year+100*month+day;//将生日化成一个整数便于比较

    if(people[i].data<=young&&people[i].data>=old)

    {

      s++;

      if(people[i].data>min)

      {

        youngest=i;min=people[i].data;

      }

      if(people[i].data<max)

      {

        oldest=i;max=people[i].data;

      }

    }

  }

  if(s) printf("%d %s %s",s,people[oldest].name,people[youngest].name);

  else printf("%d",s);

  return 0;

}

1032 挖掘机技术哪家强 (20 分)

就是一个统计问题,输入的参赛者信息统计到学校。

1041 考试座位号 (15 分)

储存数据后查找并输出

1046 划拳 (15 分)

每一轮记录一下

 

1050 螺旋矩阵 (25 分)

本题要求将给定的 N 个正整数按非递增的顺序,填入“螺旋矩阵”。所谓“螺旋矩阵”,是指从左上角第 1 个格子开始,按顺时针螺旋方向填充。要求矩阵的规模为 m n 列,满足条件:m×n 等于 Nmn;且 mn 取所有可能值中的最小值。

输入格式:

输入在第 1 行中给出一个正整数 N,第 2 行给出 N 个待填充的正整数。所有数字不超过 10^4,相邻数字以空格分隔。

输出格式:

输出螺旋矩阵。每行 n 个数字,共 m 行。相邻数字以 1 个空格分隔,行末不得有多余空格。

 

最初的思路是先排序,然后往二维数组里一圈一圈的填,先确定上下左右的界限,每填一行或一列时就转向并更新边界。不过弄了半天有几个点没过去而且还有一个超时了。

至少我确定行列数的方法。。。。居然是错的,,,我参考了别人的修改了一下,就多过了好几个点,还有一个超时,我在最开始定义了10000*10000的数组,而实际上太大了,m,n最大也就100的数量级,所以我换成了在求出m,n后再定义数组就过了。这背后的原理,我现在还无法搞明白。

#include <stdio.h>

#include <algorithm>

using namespace std;

int m,n,s,num[10000];

 

void set()

{

  int min=s;

for(int i=0;i<=s;i++){

        for(int j=0;j<=i;j++){

            if(i*j==s&&(i-j)<min){//在符合条件的数中寻找差最小的数,并记录下来

                min=i-j;

                m=i;

                n=j;

            }

        }   

    }

}

bool cmp(int a,int b)

{

return a>b;

}

int main()

{

scanf("%d",&s);

for(int i=0;i<s;i++)

{

scanf("%d",&num[i]);

}

sort(num,num+s,cmp);

set();

int ans[m][n];

int flag=0,x=0,y=0,zuo=0,you=n-1,shang=0,xia=m-1;//上下左右界限

for(int i=0;i<s;i++)

{

 

switch (flag%4)//确定方向

{

case 0:

ans[y][x++]=num[i];

if(x>you)

{

x=you;flag++;shang++;y++;

}

break;

case 1:

        ans[y++][x]=num[i];

if(y>xia)

{

y=xia;flag++;you--;x--;

}

break;

case 2:

        ans[y][x--]=num[i];

if(x<zuo)

{

x=zuo;flag++;xia--;y--;

}

break;

case 3:

        ans[y--][x]=num[i];

if(y<shang)

{

y=shang;flag++;zuo++;x++;

}

break;

}

}

for(int i=0;i<m;i++)

{

for(int j=0;j<n;j++)

{

printf("%d",ans[i][j]);if(j<n-1) printf(" ");

}

printf("\n");

}

return 0;

}

1053 住房空置率 (20 分)1061 判断题 (15 分)

又是统计

1066 图像过滤 (15 分)水题

1071 小赌怡情 (15 分)

并没那么难入手,不过细节不要忘了

#include <iostream>

using namespace std;

int main(){

    int T,K;

    int n1,b,t,n2;

    cin>>T>>K;

    for(int i=0;i<K;i++){

        cin>>n1>>b>>t>>n2;

        if(t>T){

            printf("Not enough tokens.  Total = %d.",T);

            cout<<endl;

            continue;

        }

        if(n1<n2&&(b==1)||(n1>n2&&(b==0))){

            T+=t;

            printf("Win %d!  Total = %d.",t,T);

        }else{

            T-=t;

            if(T==0){

                printf("Lose %d.  Total = %d.",t,T);

                cout<<endl;

                printf("Game Over.");

                break;

            }else{

                printf("Lose %d.  Total = %d.",t,T);

            }

 

        }

        cout<<endl;

    }

    return 0;

}

1076 Wifi密码 (15 分)老套路

1077 互评成绩计算 (20 分)

#include <stdio.h>

#include <algorithm>

bool cmp(int a,int b)

{

return a>b;

}

using namespace std;

int score[100][100],ans[100]={0};

int main()

{

int n,m;

scanf("%d%d",&n,&m);

for(int i=0;i<n;i++)

{

int bad=0;

scanf("%d",&ans[i]);//以老师的分数为基

for(int j=0;j<n-1;j++)//记录各组的分数,自己不给自己评

{

scanf("%d",&score[i][j]);

if(score[i][j]<0||score[i][j]>m) //瞎评的分数

{

score[i][j]=-1;bad++;

}

}

sort(score[i],score[i]+n-1,cmp);//降序排序

int t=n-1-bad;//有效分数的个数

double sum=0;

for(int j=1;j<t-1;j++) sum+=score[i][j];//

sum/=t-2;

ans[i]=(sum+ans[i])/2+0.5;

}

for(int i=0;i<n;i++) printf("%d\n",ans[i]);

return 0;

}

1086 就不告诉你 (15 分)

1088 三人行 (20 分)

#include <iostream>

#include <math.h>

using namespace std;

void print(double a,int m)//输出

{

if(m<a) cout<<"Cong";

else if(m==a) cout<<"Ping";

else cout<<"Gai";

}

int main() {

    int m,x,y;

    cin>>m>>x>>y;

    int a,b;

    for(a=99;a>=10;a--)//由于确定了是两位数

    {

     b=a/10+10*(a%10);//b

    double c=1.0*abs(a-b)/x;//注意c不一定是整数,否则一个点不过

     if(b==y*c)//判断是否符合

{

cout<<a<<' ';

print(a,m);cout<<' ';

print(b,m);cout<<' ';

print(c,m);return 0;

}

}

cout<<"No Solution";

 

    return 0;

 

}

1089 狼人杀-简单版 (20 分)

以下文字摘自《灵机一动·好玩的数学》:“狼人杀”游戏分为狼人、好人两大阵营。在一局“狼人杀”游戏中,1 号玩家说:“2 号是狼人”,2 号玩家说:“3 号是好人”,3 号玩家说:“4 号是狼人”,4 号玩家说:“5 号是好人”,5 号玩家说:“4 号是好人”。已知这 5 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有狼人撒谎但并不是所有狼人都在撒谎。扮演狼人角色的是哪两号玩家?

本题是这个问题的升级版:已知 N 名玩家中有 2 人扮演狼人角色,有 2 人说的不是实话,有狼人撒谎但并不是所有狼人都在撒谎。要求你找出扮演狼人角色的是哪几号玩家?

输入格式:

输入在第一行中给出一个正整数 N5N100)。随后 N 行,第 i 行给出第 i 号玩家说的话(1iN),即一个玩家编号,用正号表示好人,负号表示狼人。

输出格式:

如果有解,在一行中按递增顺序输出 2 个狼人的编号,其间以空格分隔,行首尾不得有多余空格。如果解不唯一,则输出最小序列解 —— 即对于两个序列 A=a[1],...,a[M] B=b[1],...,b[M],若存在 0k<M 使得 a[i]=b[i] ik),且 a[k+1]<b[k+1],则称序列 A 小于序列 B。若无解则输出 No Solution

 

实在没有什么好方法了,在看别人的方法有比较简洁的。大概就是选2个狼人,再检验是否满足撒谎的只有11狼。我用数组做了一次却不对。