• PAT2022年春季考试甲级,题解


    仅提供个人思路~

    题目链接:购买考试券 - PAT(甲级)2022年春仿真卷 (pintia.cn)

    7-1 Simple Lie Detection (20 分)

    /*
        n道题,阈值为t(分数超过t要输出!!!) ,k个作答
        判题规则: 
        1.字符串首字母为f,分数-2
        2.字符串尾字母为a,分数-1
        3.每个相同相同字母的len>5的最长答案段,分数+3
            即aaaaaaabbbbbbccccccc,分数为9
        4.字母a后为e或者h,分数-4
        5.连续递增字母且len>3,分数+5 
    */
    
    #include<bits/stdc++.h>
    using namespace std;
    int main()
    {
        int n,t,k;
        cin>>n>>t>>k;
        while(k--)
        {
            int res=0;
            string s;
            cin>>s;
            if(s[0]=='f')res-=2;
            if(s[n-1]=='a')res-=1;
            
            //for every longest segment of answeres where the same letter is chosen for consecutive questions, 
            //if the segment length is larger than 5, the score is to +3;
            //记录每个字母的最长连续段 
            int longest_len[200]={0};
            for(int i=0;i<n;)
            {
                int tmp_len=0;
                if(i+5<n&&s[i]==s[i+1]&&s[i]==s[i+2]&&s[i]==s[i+3]&&s[i]==s[i+4]&&s[i]==s[i+5])
                {
                    i+=5;
                    tmp_len+=5;
                    while(s[i]==s[i+1]&&i+1<n)i++,tmp_len++;
                }
                else i++;
                if(tmp_len>longest_len[s[i-1]])longest_len[s[i-1]]=tmp_len;
            }
            //验证字母的连续段是否与longest_len相符,是则+5 
            for(int i=0;i<n;)
            {
                int tmp_len=0;
                if(i+5<n&&s[i]==s[i+1]&&s[i]==s[i+2]&&s[i]==s[i+3]&&s[i]==s[i+4]&&s[i]==s[i+5])
                {
                    i+=5;
                    tmp_len+=5;
                    while(s[i]==s[i+1]&&i+1<n)i++,tmp_len++;
                }
                else i++;
                if(tmp_len==longest_len[s[i-1]]&&tmp_len)res+=3;
            }
            //注意every,测试点1和4会卡 
            for(int i=0;i+1<n;)
            {
                if(s[i]=='a'&&s[i+1]=='e'||s[i]=='a'&&s[i+1]=='h')
                {
                    res-=4;
                    i+=2;
                }
                else i++;
            }
            
            for(int i=0;i<n;)
            {
                if(i+3<n&&s[i+1]==s[i]+1&&s[i+2]==s[i]+2&&s[i+3]==s[i]+3)
                {
                    res+=5;
                    i+=3;
                    while(s[i+1]==s[i]+1&&i+1<n)i++;
                }
                else i++;
            }
            
            if(res>t) cout<<res<<"!!!"<<endl;
            else cout<<res<<endl;
        }
        return 0;
    } 
    View Code

    7-2 The First K Largest Numbers (25 分)

    #include<bits/stdc++.h>
    using namespace std;
    //存1e6会内存超限 
    int a[100];
    bool cmp(int n1,int n2)
    {
        return n1>n2;
    }
    int main()
    {
        int n,k;
        //cin会超时 
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;i++)
        {
            //只存前k+1个数并进行排序,很经典的面试题~ 
            //优先队列、multiSet、map等都可以过这题,try a try 
            int tmp=min(i,k+1);
            scanf("%d",&a[tmp]);
            sort(a+1,a+tmp+1,cmp);
        }
        for(int i=1;i<=k&&i<=n;i++)
        {
            if(i==1)printf("%d",a[i]);
            else printf(" %d",a[i]);
        }
        printf("\n");
        
        return 0;
    } 
    View Code

    7-3 Is It A Binary Search Tree - Again (25 分)

    #include<bits/stdc++.h>
    using namespace std;
    int n,t[2050];
    int a[2050],len=1;
    //二叉搜索树的中序变历为升序 
    void inOrder(int cur)
    {
        if(t[cur]==-1||cur>n)return;
        inOrder(cur*2);
        a[len++]=t[cur];
        inOrder(cur*2+1);
    }
    
    int main()
    {
        cin>>n;
        for(int i=1;i<=n;i++)cin>>t[i];
        inOrder(1);
        
        int b[2050]={0};
        for(int i=1;i<len;i++)b[i]=a[i];
        sort(b+1,b+len);
        
        //用b(排序后的a)判断a是否为升序 
        bool flag=0;
        for(int i=1;i<len;i++)
        {
            if(b[i]!=a[i])flag=1;
        }
        if(!flag)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
        
        for(int i=1;i<len;i++)
        {
            if(i==1)cout<<a[i];
            else cout<<" "<<a[i];
        }
        cout<<endl;
        return 0;
    }
    View Code

    7-4 The Rescue (30 分)

    /*        
            0
            ↑
        3←       →1
            ↓
            2 
    
        ?为人所在位置 
        有三个距离最远(4)位置,pick了代码最small的,给了他0011指令
            ?#???
            ??X??
            ??##?
            ???#?
        起初图中所有0点都可能有人,所有人执行指令0011后(撞墙不走、到X不走),可能在四个?点处 
            ?#OO?
            OOXO?
            OO##O
            OO?#O
        pick了距离最远(4)的最下面一排的问号,给了他3001指令...... 
        
        
        ans的本质是:所以遍布在各个位置的人,听到这些指令后一一执行,或早或晚最后都能到X这个位置 
    
    */
    
    #include<bits/stdc++.h>
    using namespace std;
    const int INF=0x3f3f3f;
    char p[105][105];
    int len[105][105],vis[105][105];
    typedef pair<int, int> PII;
    map<PII,int> is_hiker;
    
    struct node
    {
        int x,y; 
        //{x,y}到X的路 
        string path;
    };
    
    //先搜出x到所有0的距离 
    void bfs(int x,int y)
    {
        memset(vis,0,sizeof vis); 
        queue<PII>q;
        q.push({x,y});
        vis[x][y]=1;
        while(!q.empty())
        {
            PII cur=q.front();
            q.pop();
            for(int i=0;i<4;i++)
            {
                int tx=cur.first,ty=cur.second;
                if(i==0)tx--;
                if(i==1)ty++;
                if(i==2)tx++;
                if(i==3)ty--;
                if(!vis[tx][ty]&&is_hiker[{tx,ty}])
                {
                    vis[tx][ty]=1;
                    len[tx][ty]=len[cur.first][cur.second]+1;
                    q.push({tx,ty});
                }
            }
        }
    }
    
    //求出{x,y}到x的最small的路,反之求不出来 
    string cal_path(int x,int y)
    {
        memset(vis,0,sizeof vis);
        queue<struct node> q;
        struct node start={x,y,""};
        q.push(start);
        vis[x][y]=1;
        while(true)
        {
            struct node cur=q.front();
            q.pop();
            for(int i=0;i<4;i++)
            {
                int tx=cur.x,ty=cur.y;
                if(i==0)tx--;
                if(i==1)ty++;
                if(i==2)tx++;
                if(i==3)ty--;
                if(!vis[tx][ty]&&p[tx][ty]!='#')
                {
                    vis[tx][ty]=1;
                    char ch='0'+i;
                    if(p[tx][ty]=='X')return cur.path+ch;
                    struct node nex={tx,ty,cur.path+ch};
                    q.push(nex);
                }
            }
        }
    }
    
    //模拟从{tx,ty}按照s指令会走到哪个位置 
    pair<int, int> walk(int tx,int ty,string s)
    {
        for(int i=0;i<s.size();i++)
        {
            //遇墙不走 
            if(s[i]=='0'&&p[tx-1][ty]!='#')tx--;
            if(s[i]=='1'&&p[tx][ty+1]!='#')ty++;
            if(s[i]=='2'&&p[tx+1][ty]!='#')tx++;
            if(s[i]=='3'&&p[tx][ty-1]!='#')ty--;
            //终点不走 
            if(p[tx][ty]=='X')return {tx,ty};
        }
        return {tx,ty};
    }
    
    int main()
    {
        int n,m;
        cin>>n>>m;
        //把边围起来 
        int x,y;
        queue<PII> hiker_place;
        for(int i=0;i<=m+1;i++)p[0][i]='#',p[n+1][i]='#',len[0][i]=len[n+1][i]=INF;
        for(int i=0;i<=n+1;i++)p[i][0]='#',p[i][m+1]='#',len[i][0]=len[i][m+1]=INF;
        for(int i=1;i<=n;i++)
        {
            getchar();
            for(int j=1;j<=m;j++)
            {
                cin>>p[i][j];
                if(p[i][j]=='X')x=i,y=j;
                if(p[i][j]=='#')len[i][j]=len[j][i]=INF;
                //hiker_place是人可能在的地方的队列集合,is_hiker是判断该点是否可能有人 
                if(p[i][j]=='O')hiker_place.push({i,j}),is_hiker[{i,j}]=1;
            }
        }
        //找X到O的最远距离 
        bfs(x,y);
            
        string ans="";
        while(!hiker_place.empty())
        {
            int max_len=0;
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    if(len[i][j]==INF)continue;
                    else if(is_hiker[{i,j}]&&len[i][j]>max_len)max_len=len[i][j];
                }
            }
    
            string tmp=""; 
            for(int i=1;i<=n;i++)
            {
                for(int j=1;j<=m;j++)
                {
                    if(is_hiker[{i,j}]&&len[i][j]==max_len)
                    {
                        string path=cal_path(i,j);
                        if(tmp==""||path<tmp)tmp=path;
                    }
                }
            }
            ans+=tmp;
            
            //清空人的位置,将该步所有人的可能位置按照tmp指令进行模拟,得到新的所有人的可能位置,赋值给queue及map 
            is_hiker.clear();
            queue<pair<int, int> > tmp_place;
            while(!hiker_place.empty())
            {
                pair<int, int> cur=hiker_place.front(),nex;
                hiker_place.pop();
                nex=walk(cur.first,cur.second,tmp);
                if(!is_hiker[nex]&&p[nex.first][nex.second]!='X')
                {
                    is_hiker[nex]=1;
                    tmp_place.push(nex);
                }
            }
            hiker_place=tmp_place;
        }
        cout<<ans<<endl;
        return 0;
    } 
    View Code
  • 相关阅读:
    这个网站的设计太独特了
    mybatis—— 一个空格引发的血案
    Java IO--实现文件的加密解密
    Intellij IDEA如何生成JavaDoc--转载
    Java 在循环里发生异常会跳出循环
    idea格式化代码快捷键
    idea创建类时默认添加头部注释信息
    maven-helper解决依赖冲突
    Octotree插件
    idea .gitignore(git文件忽略)
  • 原文地址:https://www.cnblogs.com/myrtle/p/15984412.html
Copyright © 2020-2023  润新知