zoukankan      html  css  js  c++  java
  • PAT-2020年春季考试_2020.07.22_线上模拟_甲级1087-1090_心得+题解

    级别:甲级

    时间2020年7月22日,下午13:30-16:30,线上模拟,双机位摄像头,需要提前一小时测试比赛环境、调整机器。

    本次模拟使用题集:PTA甲级1087、1088、1089、1090

    监考客户端下载:https://pintia.cn/problem-sets?tab=0

    1087(第四题):

    #include<bits/stdc++.h>
    using namespace std;
    const int inf=0x3f3f3f3f;
    const int maxn=250;
    string s[maxn],start;//,res;
    int val[maxn],G[maxn][maxn];
    bool vst[maxn];
    map<string,int>mp;
    map<int,string>mp2;
    int num[1000000],cost=inf,happy,avehappy,happynum,_end;
    int n,k;
    
    
    int a[maxn],tmp[maxn];
    void dfs(int cur,int _cost,int _happy,int _happynum)
    {
        tmp[_happynum]=cur;
        //cout<<_happynum<<" "<<cur<<endl;
        if(cur==_end)
        {
            //cout<<cur<<" "<<_cost<<" "<<_happy<<" "<<_happynum<<endl;
            //for(int i=0;i<=_happynum;i++)cout<<tmp[i]<<" ";
            //cout<<endl;
            num[_cost]++;
            if(_cost<cost)
            {
                cost=_cost;
                happy=_happy;
                happynum=_happynum;
                for(int i=0;i<=_happynum;i++)a[i]=tmp[i];
            
            }
            else if(_cost==cost)
            {
                if(_happy>happy)
                {        
                    cost=_cost;
                    happy=_happy;
                    happynum=_happynum;
                    for(int i=0;i<=_happynum;i++)a[i]=tmp[i];
        
                }
                else if(_happy==happy&&_happynum<happynum)
                {
                    cost=_cost;
                    happy=_happy;
                    happynum=_happynum;
                    for(int i=0;i<=_happynum;i++)a[i]=tmp[i];
        
                }
            }
            return;
        }
        for(int i=0;i<n;i++)
        {
            if(G[cur][i]!=-1&&!vst[i])
            {
                vst[i]=1;
                
                dfs(i,_cost+G[cur][i],_happy+val[i],_happynum+1);
                vst[i]=0;
            }
        }
    }
    int main()
    {
        cin>>n>>k>>start;
        mp[start]=0;
        mp2[0]=start;
        for(int i=1;i<n;i++)
        {
            cin>>s[i]>>val[i];
            mp[s[i]]=i;
            mp2[i]=s[i];
            if(s[i]=="ROM")_end=i;
        }
        memset(G,-1,sizeof G);
        for(int i=0;i<k;i++)
        {
            string s1,s2;
            int cst;
            cin>>s1>>s2>>cst;
            G[mp[s1]][mp[s2]]=G[mp[s2]][mp[s1]]=cst;
        }
    
        vst[0]=1;
        dfs(0,0,0,0);
        
        double avehappy=happy/happynum;
        cout<<num[cost]<<" "<<cost<<" "<<happy<<" "<<avehappy<<endl;
        for(int i=0;i<happynum;i++)
        {
            cout<<mp2[a[i]]<<"->";
        }
        cout<<"ROM"<<endl;
        //cout<<res<<endl;
        
        return 0;
    }
    View Code
    #include<bits/stdc++.h>
    using namespace std;
    const int inf=0x3f3f3f;
    const int maxn=250;
    string s[maxn],start,res;
    int val[maxn],G[maxn][maxn];
    bool vst[maxn];
    map<string,int>mp;
    map<int,string>mp2;
    int num[1000000],cost=inf,happy,avehappy,happynum,_end;
    int n,k;
    void dfs(int cur,int _cost,int _happy,int _happynum,string s)
    {
        if(cur==_end)
        {
            //cout<<cur<<" "<<_cost<<" "<<_happy<<" "<<_happynum<<" "<<s<<endl;
            num[_cost]++;
            if(_cost<cost)
            {
                cost=_cost;
                happy=_happy;
                happynum=_happynum;
                res=s;
            }
            else if(_cost==cost)
            {
                if(_happy>happy)
                {        
                    cost=_cost;
                    happy=_happy;
                    happynum=_happynum;
                    res=s;
                }
                else if(_happy==happy&&_happynum<happynum)
                {
                    cost=_cost;
                    happy=_happy;
                    happynum=_happynum;
                    res=s;
                }
            }
            return;
        }
        for(int i=0;i<n;i++)
        {
            if(G[cur][i]!=-1&&!vst[i])
            {
                vst[i]=1;
                dfs(i,_cost+G[cur][i],_happy+val[i],_happynum+1,s+"->"+mp2[i]);
                vst[i]=0;
            }
        }
    }
    int main()
    {
        cin>>n>>k>>start;
        mp[start]=0;
        mp2[0]=start;
        for(int i=1;i<n;i++)
        {
            cin>>s[i]>>val[i];
            mp[s[i]]=i;
            mp2[i]=s[i];
            if(s[i]=="ROM")_end=i;
        }
        memset(G,-1,sizeof G);
        for(int i=0;i<k;i++)
        {
            string s1,s2;
            int cst;
            cin>>s1>>s2>>cst;
            G[mp[s1]][mp[s2]]=G[mp[s2]][mp[s1]]=cst;
        }
    
        vst[0]=1;
        dfs(0,0,0,0,mp2[0]);
        
        avehappy=happy/happynum;
        cout<<num[cost]<<" "<<cost<<" "<<happy<<" "<<avehappy<<endl;
        cout<<res<<endl;
        
        return 0;
    }
    View Code

    1088(第一题):

    #include<bits/stdc++.h>
    using namespace std;
    void cal(long long a,long long b)
    {
        long long ans,a2,b2;
        if(b==0)
        {
            cout<<"Inf";
            return;
        }
        if(b<0)a=-a,b=-b;
        if(a==0)
        {
            cout<<0;
        }
        else if(a>0)
        {
            ans=a/b,a2=a%b,b2=b;
            int tmp=__gcd(a2,b2);
            a2=a2/tmp;
            b2=b2/tmp;
            if(a2==0)cout<<ans;
            else if(ans==0)cout<<a2<<"/"<<b2;
            else cout<<ans<<" "<<a2<<"/"<<b2;
        }
        else 
        {
            a=-a;
            ans=a/b,a2=a%b,b2=b;
            int tmp=__gcd(a2,b2);
            a2=a2/tmp;
            b2=b2/tmp;
            cout<<"(-";
            if(a2==0)cout<<ans;
            else if(ans==0)cout<<a2<<"/"<<b2;
            else cout<<ans<<" "<<a2<<"/"<<b2;
            cout<<")";
        }
    }
    void sol(long long a,long long b,long long c,long long d,char ch)
    {
        if(ch=='+')
        {
            cal(a*d+b*c,b*d);
        }
        else if(ch=='-')
        {
            cal(a*d-b*c,b*d);
        }
        else if(ch=='*')
        {
            cal(a*c,b*d);
        }
        else 
        {
            cal(a*d,b*c);
        }
    }
    int main()
    {
        long long a,b,c,d;
        scanf("%lld/%lld %lld/%lld",&a,&b,&c,&d);
        //cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;
        cal(a,b);cout<<" + ";cal(c,d);cout<<" = ";sol(a,b,c,d,'+');cout<<endl;
        cal(a,b);cout<<" - ";cal(c,d);cout<<" = ";sol(a,b,c,d,'-');cout<<endl;
        cal(a,b);cout<<" * ";cal(c,d);cout<<" = ";sol(a,b,c,d,'*');cout<<endl;
        cal(a,b);cout<<" / ";cal(c,d);cout<<" = ";sol(a,b,c,d,'/');cout<<endl;
        
        return 0;
    } 
    View Code

    1089(第二题):

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=200;
    int a[maxn],b[maxn];
    int tmp[maxn],n;
    bool cmp()
    {
        /*
        for(int i=0;i<n;i++)
        {
            cout<<tmp[i]<<" ";
        }
        cout<<endl;
        */
        for(int i=0;i<n;i++)
        {
            if(tmp[i]!=b[i])return false;
        }
        return true;
    }
    
    void Insertion()
    {
        for(int i=0;i<n;i++)tmp[i]=a[i];
        for(int i=2;i<=n;i++)//如果i从1开始,Merge函数要运行在Insertion函数前 
        {
            sort(tmp,tmp+i); 
            if(cmp())
            {
                int last=min(i+1,n);
                sort(tmp,tmp+last);
                cout<<"Insertion Sort"<<endl;
                for(int j=0;j<n-1;j++)cout<<tmp[j]<<" ";
                cout<<tmp[n-1]<<endl;
                exit(0);
            }
        }
    }
    void Merge()
    {
        for(int i=0;i<n;i++)tmp[i]=a[i];
        for(int i=1;;i*=2)
        {
            for(int j=0;j<n;j+=i)
            {
                int l=j,r=min(j+i,n);
                sort(tmp+l,tmp+r);
                
                //cout<<l<<" "<<r-1<<endl;
                //merge(j,j+i);
            }
            
            if(cmp())
            {
                cout<<"Merge Sort"<<endl;
                i*=2;
                for(int j=0;j<n;j+=i)
                {
                    int l=j,r=min(j+i,n);
                    sort(tmp+l,tmp+r);
                }
            
                for(int j=0;j<n-1;j++)cout<<tmp[j]<<" ";
                cout<<tmp[n-1]<<endl;
                exit(0);
            }
            if(i>n)break;
        }
    }
    
    int main()
    {
        cin>>n;
        for(int i=0;i<n;i++)cin>>a[i];
        for(int i=0;i<n;i++)cin>>b[i];
        Insertion();
        Merge();
        
        
        return 0;
    }
    View Code

    1090(第三题):

    #include<bits/stdc++.h>
    using namespace std;
    const int maxn=1e5+10;
    int a[maxn],ans=0,b[maxn];
    vector<int> v[maxn];
    void dfs(int cur,int len)
    {
        int size=v[cur].size();
        if(size==0)
        {
            ans=max(ans,len);
            b[len]++;
            return;
        }
        for(int i=0;i<size;i++)
        {
            dfs(v[cur][i],len+1);
        }
    }
    int main()
    {
        //cout<<1.80*1.01*1.01*1.01<<endl;
        int n,start=0;
        long double p,r;
        cin>>n>>p>>r;
        for(int i=0;i<n;i++)
        {
            cin>>a[i];
            if(a[i]==-1)start=i;
            else v[a[i]].push_back(i);
        }
        dfs(start,0);
        //cout<<ans<<endl;
        for(int i=0;i<ans;i++)
        {
            p=p+p*r*0.01;
            //cout<<p<<endl;
        }
        printf("%.2Lf %d
    ",p,b[ans]);
        //cout<<p<<" "<<b[ans]<<endl;
        
        
        return 0;
    }
    View Code

    先开第一题,模拟模得头裂了,竟然过了

    再看第二题,看得焦头烂额,跳过看别的题

    看了两遍第三题,还是没看懂题目,研究了一下样例,貌似懂了一些什么......试了一下然后一发入魂,这个时候还有2hour42min

    第三道开的是第四题,本来以为是最短路板子题,后来发现不大行,于是改了一下用了dfs,but最后两个点wa了(23/30),怀疑过avehappy的取整,怀疑过string的长度会不会不够,改完代码之后于事无补,最后发现记录cost最大值的数组开小了,开到1e6之后就过了,这个时候还有1hour22min

    最后折回来看第二题,跟着样例学了一发插入排序和归并排序,用sort取巧了,妙得我只想写题解233。不过有个点wa掉了(24/25),盲猜是序列和原序列相同时应该判为Merge sort,写完四题还剩50min

    写到第三题的时候看了一眼榜,已经有人AK了,真是巨佬啊......

    总体感觉挺愉快~没有被特殊样例卡掉的场次就是好场次

    不过考到一半转过头发现后面的机位上显目的qq消息,感觉人都傻了,正式赛一定退qq!

    tips:

    万能头可以用,所有图论都能开邻接矩阵(不用背邻接表),最短路基本上都可以用dijstra(不用背kruskal),用不到set,基本上map和vector就完事了

    刷题请倒序!!!近几年真题题型重复率大,没有时间还要正着刷的都是耍流氓!

    自用dijstra板子:

    #include <iostream>
    #include <string.h>
    using namespace std;
    const int inf=0x3f3f3f3f;
    int G[110][110];
    int dist[110];
    bool vst[110];
    int n,m;
    void dijkstra(int s)
    {
        memset(vst,false,sizeof(vst));
        memset(dist,0x3f,sizeof(dist));
        dist[s]=0;
        for(int i=0;i<n;i++)
        {
            int v,min_d=inf;
            for(int j=1;j<=n;j++)
            {
                if(!vst[j]&&dist[j]<min_d)
                {
                    min_d=dist[j];
                    v=j;
                }
            }
            vst[v]=true;
            for(int j=1;j<=n;j++)
            {
                dist[j]=min(dist[j],dist[v]+G[v][j]);
            }
        }
    }
    int main() {
        cin>>n>>m;
        memset(G,0x3f,sizeof(G));
        for(int i=0;i<m;i++)
        {
            int u,v,len;
            cin>>u>>v>>len;
            G[u][v]=G[v][u]=len;
        }
        dijkstra(1);
        for(int i=1;i<=n;i++)
        {
            cout<<dist[i]<<" ";
        }
        return 0;
    }
    View Code

    自用并查集板子:

    //初始化
    void init() {
        for (int i = 1; i <= n; ++i) {
            father[i] = i;
        }
    }
    //查找
    int get(int x) {
        if (father[x] == x) { // x 结点就是根结点
            return x;
        }
        return get(father[x]); // 返回父结点的根结点
    }
    //合并
    void merge(int x, int y) {
        x = get(x);
        y = get(y);
        if (x != y) { // 不在同一个集合
            father[y] = x;
        }
    }
    View Code

    自用前序中序后序转换板子(柳婼版):

    自用拓扑排序:

    // 使用邻接表存储,若对此数据结构不熟悉,请学习邻接表相关的课程内容
    struct edge {
        int v, next;
    } e[MAX_M];
    int p[MAX_N], eid;
    
    
    int topo() {
        queue<int> q;
        for (int i = 1; i <= n; i++) {
              if (indegree[i] == 0) {  // 将所有入度为零的顶点入队
                q.push(i);
            }
        }
    
    
        while (!q.empty()) {
            int now = q.front();
            cout << "visiting " << now << endl;
            q.pop();
            for (int i = p[now]; i != -1; i = e[i].next) {
                int v = e[i].v;
                indegree[v]--;
                if (indegree[v] == 0) {  // 将入度新变成零的顶点入队
                    q.push(v);
                }
            }
        }
    }
    View Code
  • 相关阅读:
    【题解】2020 年电子科技大学 ACMICPC 暑假前集训 数据结构
    【逆向】某触控板驱动分析过程
    SME 2019 ACM 题解
    数据结构 & 算法模板汇总
    VS2010win32下cocos2dx控制台打印的方法
    CDMA写码与鉴权(转载)
    mapxtreme开发小结2(c#)
    LONG GetWindowLong函数功能
    无边框的对话框的大小拖动实现
    YUV介绍
  • 原文地址:https://www.cnblogs.com/myrtle/p/13363916.html
Copyright © 2011-2022 走看看