All for PAT秋考 | 2019浙大CS复试上机

为了这几道题,充值了30块,然后还是没100 = =,96分,最后一题最后一个测试超时,就这样吧。
0907 下午13:35 (´Д` )( ;´Д`)
现在距离考试还有23小时,刷ZJU考研群,看到D题最后一个case超时的解决方法:
可以dijkstra救护车中心(最多10次),保存dist(10个中心 ✖️ 1000个救护点 个最短路径长),然后查询的时候查dist表就行啦,我直接对每个查询Dij真是无脑啊我。

7-1 Conway's Conjecture

题意:

质因数分解(因子从小到大)、然后次数大于1的因数后面拼上次数,连起来获得一个新数,判断新数是否是素数。(一开始理解错了题意,以为要算好几轮= = ,出现素数或者怎样才结束。)
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.
但很明显,题意是只算一轮。

#include 
#include 
#include 

typedef long long LL;
using namespace std;
struct Factor {
    int value, exps;
};
vector facs;

bool isPrime(LL t) {
    if (t == 0 || t == 1) return false;
    int bound = sqrt(t);
    for (int i = 2; i <= bound; ++i) {
        if (t % i == 0) return false;
    }
    return true;
}

LL vec2int() {
    LL newint = 0;
    for (auto item:facs) {
        int temp = item.value, tt = 10;
        while (tt < temp) tt *= 10;
        newint *= tt;
        newint += item.value;
        if (item.exps > 1) {
            if (item.exps >= 10)
                newint *= 100;
            else newint *= 10;
            newint += item.exps;
        }
    }
    return newint;
}

int main() {
    LL ori_num;
    scanf("%lld", &ori_num);
    if (ori_num == 1) {
        printf("1\nNo\n");
        return 0;
    }
    int temp_fac = 2, temp_exp = 0;
    while (ori_num >= 1) {
        if (ori_num % temp_fac != 0) {
            if (temp_exp != 0) {
                facs.emplace_back(Factor{temp_fac, temp_exp});
                if (ori_num == 1) break;
            }
            temp_exp = 0, temp_fac++;
        } else {
            temp_exp++;
            ori_num /= temp_fac;
        }
    }
    ori_num = vec2int();
    printf("%lld\n", ori_num);
    printf(isPrime(ori_num) ? "Yes\n" : "No\n");
    return 0;
}

7-2 Play with Linked List

题意

链表重排,k n k-1 n-1 k-2 n-2 .......。
要假装重排,所以在Node中加上自身地址addr,order字段,order表示重排前的次序。从root开始串一下,给order赋值,按order再sort一波。然后新次序数组就直接存排序后的下标就好。注意倒着混排结束之后可能还没结束!!!还要连续输出未结束的一拨中剩下的!!!

#include 
#include 

#define INF 0x3ffffff
using namespace std;

struct Node {
    int addr, value, next, no = INF;

    bool operator<(const Node &n2) const {
        return no < n2.no;
    }
};

int main() {
    Node nodes[100001];
    int head, nn, kk;
    scanf("%d%d%d", &head, &nn, &kk);
    int addr, value, next;
    for (int i = 0; i < nn; ++i) {
        scanf("%d%d%d", &addr, &value, &next);
        nodes[addr].addr = addr, nodes[addr].value = value, nodes[addr].next = next;
    }
    int curr = head, order = 0;
    while (curr != -1) {
        nodes[curr].no = order++;
        curr = nodes[curr].next;
    }
    sort(nodes, nodes + 100001);
    int new_order[100001], i1 = kk - 1, i2 = order - 1, ii;
    for (ii = 0; ii < order; ii++) {
        if (ii % 2 == 0 && i1 >= 0) new_order[ii] = i1--;
        else if (ii % 2 && i2 >= kk) new_order[ii] = i2--;
        else break;
    }
    while (i1 >= 0) new_order[ii++] = i1--;
    while (i2 >= kk) new_order[ii++] = i2--;
    for (int i = 0; i < order - 1; ++i) {
        printf("%05d %d %05d\n", nodes[new_order[i]].addr,
               nodes[new_order[i]].value, nodes[new_order[i + 1]].addr);
    }
    printf("%05d %d -1\n", nodes[new_order[order - 1]].addr,
           nodes[new_order[order - 1]].value);
    return 0;
}

7-3 Unsuccessful Searches

题意

the average search time for unsuccessful searches,hash线性探测不成功查找的平均查找次数。题目保证插入元素数不超过hashtable的大小

  • 一定要搞清楚概念:查找起始下标只能是[ 0, hash_key - 1 ]查找不成功即一直向后找,直到找到一个空位或又回到最初的起点(table_size + 1 次)……
#include 

int main() {
    int tSize, hash, nn, curr;
    bool table[1001] = {false};
    scanf("%d%d%d", &tSize, &hash, &nn);
    for (int i = 0; i < nn; ++i) {
        scanf("%d", &curr);
        curr = curr % hash;
        while (table[curr % tSize]) curr++;
        table[curr % tSize] = true;
    }
    int total = 0;
    for (int i = 0; i < hash; ++i) {
        int temp = 0;
        while (table[(i + temp) % tSize]) {
            temp++;
            if (temp == tSize) break;
        }
        total += (temp + 1);
    }
    printf("%.1lf", total * 1.0 / hash);
    return 0;
}

7-4 Ambulance Dispatch

题意

花里胡哨单源最短路。救护车调度。Dijkstra确定dist数组,回溯并比较下面的几个标尺。

每次在现在还有车的救护车中心里选一个派车,标尺依次为

  1. 呼叫位置到救护车中心的距离短的派车。
  2. 若距离相同,让车更多的中心派车。
  3. 若距离一样、车也一样多,找经过道路条数最少的。

辛辛苦苦调试俩小时,喜提26分,是的最后一个点超时了……测的是1000个结点的情况……嗯 这题大概目前只有一个满分。。。。。。真AC我会膨胀的(想的美

测试点2:注意可能经过已经没车的救护车中心呀!!!路径输出要注意!(6分)

#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define INF 0x3ffffff
using namespace std;
int graph[1020][1020], n_spot, n_ambu;
int rest_ambu[11] = {0}, dist[1020], call;
set pre[1020];

int getIndex() {
    stringstream ss;
    string str;
    cin >> str;
    int index, extra = 0;
    if (str[0] == 'A') {
        str.erase(0, 2);
        extra = n_spot;
    }
    ss << str;
    ss >> index;
    return index + extra;
}

void Dijkstra(int src) {
    bool visited[1020] = {false};
    fill(dist, dist + 1020, INF);
    for (int i = 0; i < 1020; ++i) {
        pre[i].clear();
    }
    dist[src] = 0;
    for (int i = 0; i < n_spot + n_ambu; ++i) {
        int curr = -1, mmin = INF;
        for (int j = 1; j <= n_spot + n_ambu; ++j) {
            if (!visited[j] && dist[j] < mmin) {
                mmin = dist[j];
                curr = j;
            }
        }
        if (curr == -1) return;
        visited[curr] = true;
        for (int j = 1; j <= n_spot + n_ambu; ++j) {
            if (!visited[j] && graph[curr][j] != INF) {
                int newd = dist[curr] + graph[curr][j];
                if (newd < dist[j]) {
                    dist[j] = newd;
                    pre[j].clear();
                    pre[j].insert(curr);
                } else if (newd == dist[j]) {
                    pre[j].insert(curr);
                }
            }
        }
    }
}

vector path, temp_path;

void DFS(int root) {
    if (root == call) {
        temp_path.emplace_back(root);
        if (temp_path.size() < path.size() || path.empty())
            path = temp_path;
        temp_path.pop_back();
        return;
    }
    temp_path.emplace_back(root);
    for (auto item:pre[root]) {
        DFS(item);
    }
    temp_path.pop_back();
}

bool cmp(int c1, int c2) {
    if (dist[c1] != dist[c2])
        return dist[c1] < dist[c2];
    return rest_ambu[c1] > rest_ambu[c2];
}

int main() {
    int total = 0;
    fill(graph[0], graph[0] + 1020 * 1020, INF);
    scanf("%d%d", &n_spot, &n_ambu);
    for (int i = 1; i <= n_ambu; ++i) {
        scanf("%d", &rest_ambu[i]);
        total += rest_ambu[i];
    }
    int mm, v1, v2, ll;
    scanf("%d", &mm);
    for (int i = 0; i < mm; ++i) {
        v1 = getIndex();
        v2 = getIndex();
        scanf("%d", &ll);
        graph[v1][v2] = graph[v2][v1] = min(graph[v1][v2], ll);
    }
    int kk;
    scanf("%d", &kk);
    for (int i = 1; i <= kk; ++i) {
        scanf("%d", &call);
        if (i > total) {
            puts("All Busy");
            continue;
        }
        Dijkstra(call);
        path.clear();
        // 给有车的救护车中心,按距离排序,距离一样则按车多的在前
        vector rest;
        for (int j = n_spot + 1; j <= n_spot + n_ambu; ++j) {
            if (rest_ambu[j - n_spot] > 0) rest.emplace_back(j);
        }
        sort(rest.begin(), rest.end(), cmp);
        // 找到有车的路径,则固定distance,比较其他同distance的center,找到车最多的,若存在tie,找路最少的
        int distance = dist[*rest.begin()], _rest_n = rest_ambu[*rest.begin() - n_spot];
        for (auto item:rest) {
            if (!path.empty() && dist[item] > distance) break;
            if (!path.empty() && _rest_n > rest_ambu[item - n_spot]) break;
            temp_path.clear();
            DFS(item);
        }
        int size = path.size();
        rest_ambu[path[0] - n_spot]--;
        printf("A-%d", path[0] - n_spot);
        for (int k = 1; k < size; ++k) {
            if (path[k] > n_spot)
                printf(" A-%d", path[k] - n_spot);
            else printf(" %d", path[k]);
        }
        printf("\n%d\n", dist[path[0]]);
    }
    return 0;
}

你可能感兴趣的:(All for PAT秋考 | 2019浙大CS复试上机)