为了这几道题,充值了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数组,回溯并比较下面的几个标尺。
每次在现在还有车的救护车中心里选一个派车,标尺依次为
- 呼叫位置到救护车中心的距离短的派车。
- 若距离相同,让车更多的中心派车。
- 若距离一样、车也一样多,找经过道路条数最少的。
辛辛苦苦调试俩小时,喜提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;
}