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;

    }
}

 

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