PAT倒计时——2天!(实战篇)

今天牺牲了写数学的时间来上机模拟了一下考试,结果。。。惨不忍睹!不忍直视!一塌糊涂!啊啊啊,吸取教训!

用的是19年的机试题,唉,菜的抠jio。

实战篇

7-1 Conway's Conjecture (20 分)

John Horton Conway, a British mathematician active in recreational mathematics, proposed a conjecture in 2014: arrange the factors of any given number in ascending order, and pull the exponents down, we can get another number. Keep doing so we must end up at a prime number. For example:

18=2×3​2​​

232=2​3​​×29

2329=17×137

17137 is a prime.

Now you are supposed to write a program to make one step verification of this conjecture. That is, for any given positive integer N, you must factorize it, and then test if the number obtained from its factors is a prime.

By the way, this conjecture has been proven false by James Davis, who has discovered a counter example: 135323853961879=13×53​2​​×3853×96179. Alas ...

Input Specification:

Each input file contains one test case which gives a positive integer N (<10​5​​).

Output Specification:

For each case, first print in a line the number obtained from N's factors. The in the next line, print Yes if the above number is a prime, or No if not.

Sample Input 1:

2329

Sample Output 1:

17137
Yes

Sample Input 2:

124

Sample Output 2:

2231
No

Sample Input 3:

87516

Sample Output 3:

2232111317
No

题目大意:给出一个数,找出它的质因数,依次拼接成一个新数,问这个数是不是素数。

题解:很简单的一道题目(虽然我愣是花了半个小时+),几个注意点:指数为1不需要加入排列;考虑输入为1的情况;注意拼接的时候溢出问题,所以凡是涉及到数值计算的题目,给我用long long 啊魂淡!

#include<stdio.h>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#include<math.h>
using namespace std;

map<long,long> getex;

long long pinjie(long long a,long long b){

    if(b==1)
        return a;

    vector<long long> temp;
    while(b!=0){
        long long g=b%10;
        //cout<<"g:"<<g<<endl;
        temp.push_back(g);
        b/=10;
    }

    for(long i=temp.size()-1;i>=0;i--){
      //  cout<<a<<" temp:"<<temp[i]<<endl;
        a=a*10+temp[i];

    }

    return a;
}

bool isprime(long long input){
    if(input<=1)
        return false;

    for(long i=2;i<=sqrt(input);i++){
        if(input%i==0)
            return false;
    }

    return true;
}

long long getfactor(long long input){

    for(long i=2;i<=sqrt(input);i++){
        long cnt=0;
        if(isprime(i)&&input%i==0){
            while(input%i==0){
                cnt++;
                input/=i;
            }
        }
        if(cnt>0)
            getex[i]=cnt;
    }

    if(input>1)
        getex[input]=1;


    map<long,long>::iterator it=getex.begin();
    long long pin=0;
    for(;it!=getex.end();it++){
      //  cout<<it->first<<" "<<it->second<<endl;
        pin=pinjie(pin,it->first);
        pin=pinjie(pin,it->second);
    }

    return pin;
}

int main(){
    long long input;

    cin>>input;

    if(input<=1){
        cout<<input<<endl;
        cout<<"No";
        return 0;
    }

    long long result=getfactor(input);

    cout<<result<<endl;
    if(isprime(result))
        cout<<"Yes"<<endl;
    else
        cout<<"No"<<endl;

    return 0;
}

 

7-2 Play with Linked List (25 分)

Given a singly linked list L​1​​→L​2​​→⋯→L​n−1​​→L​n​​ and an integer 1≤k<n, you are supposed to rearrange the links to obtain a list like L​k​​→L​n​​→L​k−1​​→L​n−1​​→⋯. For example, given L being 1→2→3→4→5→6 and k=4, you must output 4→6→3→5→2→1.

Input Specification:

Each input file contains one test case. For each case, the first line contains the address of the first node, a positive N (≤10​5​​) which is the total number of nodes, and an integer 1≤k<n where n is the number of nodes in the linked list. The address of a node is a 5-digit nonnegative integer, and NULL is represented by -1.

Then N lines follow, each describes a node in the format:

Address Data Next

where Address is the position of the node, Data is a positive integer no more than 10​5​​, and Next is the position of the next node. It is guaranteed that there are at least two nodes on the list.

Output Specification:

For each case, output in order the resulting linked list. Each node occupies a line, and is printed in the same format as in the input.

Sample Input:

00100 6 4
00000 4 99999
00100 1 12309
68237 6 -1
33218 3 00000
99999 5 68237
12309 2 33218

Sample Output:

00000 4 68237
68237 6 33218
33218 3 99999
99999 5 12309
12309 2 00100
00100 1 -1

 

题目大意:给出链表,你给改成从第k个结点开始和尾节点从后往前交替输出,例如1→2→3→4→5→6 and k=4, you must output 4→6→3→5→2→1.

题解:将第1-k个结点加入第一个数组first,第k+1-n个结点加入第二个数组second,交替输出这两个数组直到有一个输出完,再把剩下那个没输出完的数组继续输出完毕。注意点:输出五位不足补零,小心别输出-00001;凡是链表的题目,给我考虑单独成链的情况!!!老记不住,什么毛病!!!

#include<stdio.h>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#include<math.h>
using namespace std;

const int maxn=100010;

struct node{
    int cur,next;
    int key;

};

node* createnode(int c,int n,int k){
        node* temp=new node;
        temp->cur=c;
        temp->next=n;
        temp->key=k;

        return temp;
    }

node link[maxn];
vector<node> first,second;

int start,num,k;

void sparate(){
    int s=start;
    bool afterk=false;
    int index=1;
    while(s!=-1){
        node curnode=link[s];

        if(!afterk){

            first.push_back(curnode);
        }else{
            second.push_back(curnode);
        }

        if(index==k){
            afterk=true;
        }
        index++;
        s=curnode.next;
    }
}

int main(){
    cin>>start>>num>>k;
    for(int i=0;i<num;i++){
        int cur,key,next;
        cin>>cur>>key>>next;

        node* temp=createnode(cur,next,key);
        link[cur]=*temp;

    }

    sparate();

    bool isfirst=true;
    int i=first.size()-1;
    int j=second.size()-1;

    //cout<<"---------------------"<<endl;
    int cnt=0;
    while(i>=0&&j>=0){

        if(isfirst){
            printf("%05d %d ",first[i].cur,first[i].key);
            i--;


            printf("%05d\n",second[j].cur);

        }else{
            printf("%05d %d ",second[j].cur,second[j].key);
            j--;

            printf("%05d\n",first[i].cur);
        }

        cnt++;
        isfirst=!isfirst;
    }

        while(i>=0){
            printf("%05d %d ",first[i].cur,first[i].key);
            i--;

            if(i<0){
                printf("-1");
            }else{
                printf("%05d\n",first[i].cur);
            }
            cnt++;
        }
        while(j>=0){
            printf("%05d %d ",second[j].cur,second[j].key);
            j--;

            if(j<0){
                printf("-1");
            }else{
                printf("%05d\n",second[j].cur);
            }
            cnt++;
        }

    return 0;
}

 

7-3 Unsuccessful Searches (25 分)

ti.JPG

The above figure is a question from GRE-CS 2018. It states:

Given an initially empty hash table HT of size 11. The hash function is H(key)=key%7, with linear probing used to resolve the collisions. Now hash the keys 87, 40, 30, 6, 11, 22, 98 and 20 one by one into HT. What is the average search time for unsuccessful searches?

The answer is 6.

Now you are supposed to write a program to solve this kind of problems.

Input Specification:

Each input file contains one test case. For each case, the first line gives 3 positive integers TSize (≤10​3​​, the table size), M (≤TSize, the divisor in the hash function), and N (≤TSize, the number of integers to be inserted). Then N non-negative integers (≤10​4​​) are given in the next line, separated by spaces.

Output Specification:

Print in a line the average search time for unsuccessful searches, after hashing the N integers into the table. The answer must be accurate up to 1 decimal place.

Sample Input 1:

11 7 8
87 40 30 6 11 22 98 20

Sample Output 1:

6.0

Sample Input 2:

3 3 3
81 2 5

Sample Output 2:

4.0

Note: In sample 2, the last test of the original position counts as well.

 

题意:hash表插入,线性检测,求失败的平均查找长度。

题解:这题没啥好讲的,只要会求平均查找长度的基本写出来一遍AC,但是!!还没复习数据结构的我不会求!!!不说了,学数据结构去了。

#include<stdio.h>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#include<math.h>
using namespace std;
const int maxn=1010;
int scale,value,num;
int table[maxn];

void insert(int data){
    int start=data%value;
    int cnt=1;
    while(cnt<=scale){
        if(table[start]==-1){
            table[start]=data;
            return;
        }


        start++;
        start%=scale;
        cnt++;
    }
}

int searchfail(int index){
    int cnt=1;

    while(cnt<=scale){
        if(table[index++]==-1)
            break;
        index%=scale;
        cnt++;
    }

    return cnt;
}

int main(){
    cin>>scale>>value>>num;

    fill(table,table+maxn,-1);
    for(int i=0;i<num;i++){
        int data;
        cin>>data;

        insert(data);
    }
    int sum=0;
    for(int i=0;i<value;i++){
        int len=searchfail(i);
        sum+=len;
    }

    double result=sum*1.0/value;

    printf("%.1lf",result);
}

7-4 Ambulance Dispatch (30 分)

Given the map of a city, with all the ambulance dispatch centers (救护车派遣中心) and all the pick-up spots marked. You are supposed to write a program to process the emergency calls. It is assumed that the callers are waiting at some pick-up spot. You must inform the nearest (that is, to take the minimum time to reach the spot) dispatch center if that center has at least one ambulance available. Note: a center without any ambulance must not be considered.

In case your options are not unique, inform the one with the largest number of ambulances available. If there is still a tie, choose the one that can pass the least number of streets to reach the spot, which is guaranteed to be unique.

Input Specification:

Each input file contains one test case. For each case, the first line contains two positive integers N​s​​ (≤10​3​​) and N​a​​ (≤10), which are the total number of pick-up spots and the number of ambulance dispatch centers, respectively. Hence the pick-up spots are numbered from 1 to N​s​​, and the ambulance dispatch centers are numbered from A−1 to A−N​a​​.

The next line gives N​a​​ non-negative integers, where the i-th integer is the number of available ambulances at the i-th center. All the integers are no larger than 100.

In the next line a positive number M (≤10​4​​) is given as the number of streets connecting the spots and the centers. Then M lines follow, each describes a street by giving the indices of the spots or centers at the two ends, followed by the time taken to pass this street, which is a positive integer no larger than 100.

Finally the number of emergency calls, K, is given as a positive integer no larger than 10​3​​, followed by K indices of pick-up spots.

All the inputs in a line are separated by a space.

Output Specification:

For each of the K calls, first print in a line the path from the center that must send an ambulance to the calling spot. All the nodes must be separated by exactly one space and there must be no extra space at the beginning or the end of the line. Then print the minimum time taken to reach the spot in the next line. It is assumed that the center will send an ambulance after each call. If no ambulance is available, just print All Busy in a line. It is guaranteed that all the spots are connected to all the centers.

Sample Input:

7 3
3 2 2
16
A-1 2 4
A-1 3 2
3 A-2 1
4 A-3 1
A-1 4 3
6 7 1
1 7 3
1 3 3
3 4 1
6 A-3 5
6 5 2
5 7 1
A-2 7 5
A-2 1 1
3 5 1
5 A-3 2
8
6 7 5 4 6 4 3 2

Sample Output:

A-3 5 6
4
A-2 3 5 7
3
A-3 5
2
A-2 3 4
2
A-1 3 5 6
5
A-1 4
3
A-1 3
2
All Busy

 

题意:给你一张图,里面有救护中心和事故发生点,给你若干个事故发生点,让你找出最适合派车的救护中心和一条最短路径。查找的约束:

1、救护中心要有车(每派遣一次少一辆车)

2、到达事故地点的时间最少(即边权最小,距离最短,经典dij)

3、如果有多个救护中心和事故发生地的最短距离一样,派拥有救护车最多的

4、如果还有一样的,派经过的大街最少的(即经过边数最少的,这个条件没用,在dij的时候直接过滤掉了)

题解:一道经典的dij题,将救护中心和事故发生点存在一个数组中,事故发生点的索引值=救护中心数+事故发生点输入值,如上例,4=3+4=7,5=3+5=8。就是将数组中前面几个空间给救护中心,后面给事故点。第一层遍历每个事故点,第二层遍历救护中心,每次遍历进行一次dij,找出最短路径,然后根据救护车数找到最佳事故中心。这题和1072很像,但是好像时间上比那个严格,我最后一个测试点超时,死活A不出来,这里就放个半对的代码吧。

 

#include<stdio.h>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<algorithm>
#include<math.h>
using namespace std;

const int maxn=1020;
const int inf=1000000000;

struct node{
    int next;
    int dist;
    node(int n,int d){
        next=n;
        dist=d;
    }
};

vector<node> G[maxn];

int num,jiunum,pnum;

int carnum[20];

int strtoint(string input){

    int sum=0;
    int add=0;
    if(input[0]=='A'){
        input.erase(0,2);
    }else{
        add=jiunum;
    }

    for(int i=0;i<input.size();i++){
        int cur=input[i]-'0';
        sum=sum*10+cur;
    }

    return sum+add;
}

int d[maxn];
bool havego[maxn];
int pre[maxn];
void dij(int s,int e){
    fill(d,d+num+10,inf);
    fill(havego,havego+num+10,false);
    fill(pre,pre+num+10,0);
    d[s]=0;
    //pre[s]=s;
    for(int i=0;i<num;i++){
        int cur=-1;
        int mdis=inf;
        for(int j=1;j<=num;j++){
            if(havego[j]==false&&d[j]<mdis){
                cur=j;
                mdis=d[j];
            }
        }

        if(cur==-1||cur==e)return;
        havego[cur]=true;

        for(int j=0;j<G[cur].size();j++){
            int next=G[cur][j].next;
            int dist=G[cur][j].dist;
            if(havego[next]==false&&d[cur]+dist<d[next]){
                d[next]=d[cur]+dist;
                pre[next]=cur;
            }
        }
    }
}

void getpath(vector<int> &temp,int e){
    while(e!=0){
        temp.push_back(e);
        e=pre[e];
    }
}

int main(){
    cin>>pnum>>jiunum;
    num=pnum+jiunum;
    for(int i=1;i<=jiunum;i++){
        cin>>carnum[i];
    }

    int line;
    cin>>line;

    for(int i=0;i<line;i++){
        string a,b;
        int a1,b1,dt;
        cin>>a>>b>>dt;
        a1=strtoint(a);
        b1=strtoint(b);

        //cout<<a1<<"a b"<<b1<<endl;
        G[a1].push_back(node(b1,dt));
        G[b1].push_back(node(a1,dt));
    }

    int k;
    cin>>k;
    for(int i=0;i<k;i++){
        int e;
        cin>>e;
        e+=jiunum;
        int maxcar=0;
        int mindist=inf;
        vector<int> result;

        bool nocar=true;
        for(int c=1;c<=jiunum;c++){
            if(carnum[c]>0){
                nocar=false;
                break;
            }
        }
        if(nocar){
                cout<<"All Busy"<<endl;
                continue;
        }
        //cout<<"jiunum"<<jiunum<<endl;
        for(int j=1;j<=jiunum;j++){
            if(carnum[j]<=0)
                continue;

            dij(j,e);
            vector<int> temp;
            getpath(temp,e);

            if(d[e]<mindist){
                result=temp;
                mindist=d[e];
                maxcar=carnum[j];
            }else if(d[e]==mindist&&carnum[j]>maxcar){
                result=temp;
                mindist=d[e];
                maxcar=carnum[j];
            }else if(d[e]==mindist&&carnum[j]==maxcar&&result.size()>temp.size()){
                result=temp;
                mindist=d[e];
                maxcar=carnum[j];
            }
        }

            int index=result[result.size()-1];
            carnum[index]--;
            for(int p=result.size()-1;p>=0;p--){
                int cur=result[p];
                if(cur>jiunum){
                    cur-=jiunum;
                    cout<<cur;
                }
                else{
                    cout<<"A-"<<cur;
                }

                if(p>0)
                    cout<<" ";

            }
            cout<<endl;

            cout<<mindist<<endl;

    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章