同类型基础题
1161-Merging Linked Lists
进阶题——分块题
1133 Splitting A Linked List
分析
- 设置3个下标完全对应的数组(构建隐式散列)
- 为了快速获得下标,构建map映射 地址——》下标
- 由于无法获得二维数组恰好的层数,因此采取尽可能大的策略(块3 9/3=3层 10/3=3则需要4层)
层数=quantity / block + 1;这样无论如何都不会超出边界 - 插入二维数组时,按照 块满 ,则层数+1 的方式来累进摆放
同时对于 每行数量不做固定,都用push_back从而达到恰好的效果
综上,这样可以对最后的二维数组 进行任何的反转输出(按行/列)
代码:1165 Block Reversing
//这个通解版本最快;即全部用散列,除了下标外 其他不用map,set去搜索
//注:改成unordered_map并没有快,甚至慢了
#include<bits/stdc++.h>
#pragma warning(disable:4996)
#pragma warning(disable:4703)
#pragma warning(disable:4700)
using namespace std;
int start, quantity, block, layers{ 0 };
vector<int> address, key, next_address;
vector<int>* print;
map<int, int>address_id;
void InPut();
void Insert(int*);
int main() {
InPut();
Insert(&start);
bool first{ true };
for (int i = layers; i >= 0; i--) {
for (auto j = print[i].begin(); j != print[i].end(); j++) {
first? printf("%05d %d ", address[*j], key[*j]), first = false: printf("%05d\n%05d %d ", address[*j], address[*j], key[*j]);
}
}
printf("-1\n");
return 0;
}
void InPut() {
scanf("%d %d %d", &start, &quantity, &block);
address.resize(quantity);
key.resize(quantity);
next_address.resize(quantity);
print = new vector<int>[quantity / block + 1];
int x, y, z;
for (int i = 0; i < quantity; i++) {
scanf("%d %d %d", &x, &y, &z);
address[i] = x;
address_id[x] = i;
key[i] = y;
next_address[i] = z;
}
}
void Insert(int* next) {
if (*next == -1) return;
int i = address_id[*next];
if (print[layers].size() == block) layers++;
print[layers].push_back(i);
Insert(&next_address[i]);
}