写在前面
所有题目大意和名字纯楼主脑记,准确还要看网上的题,但代码都没问题。
这次最大的问题竟然是读题不认真,7-1和7-3一直没过,后来看代码没问题,重新读题发现求的方向不对,改正后即A了。
7-1 Arrays and Linked Lists (20 分)
知识点:模拟
题意:
大致是描述了一种数据结构,是数组和链表的结合,告诉你几个顺序相连数组的初始地址和大小,然后查询编号是q的数字的地址,如果这个数组链表装不下,则输出
Illegal Access.
最后一行输出需要建立的数组的最小个数.
注意:
即使所有的查询都不成立,也要建立1个,因为最初至少有一个。
Simple Input:
6 7
2048 5
128 6
4016 10
1024 7
3072 12
9332 10
2 12 25 50 28 8 39
Simple Output:
2056
4020
1040
Illegal Access
3072
140
3116
5
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
ll add;
ll s;
};
vector<node>v;
int main()
{
int n, k;
scanf("%d %d", &n, &k);
v.resize(n);
ll sx = 0;
for (int i = 0; i < n; ++i)
{
scanf("%lld %lld", &v[i].add, &v[i].s);
sx += v[i].s;
}
set<int>s;
ll mt = 0;
for (int kk = 0; kk < k; ++kk)
{
ll q;
scanf("%lld", &q);
ll i = 0;
ll sz = 0;
if (q >= sx)
{
printf("Illegal Access\n");
continue;
}
while (i < n && q >= sz)
{
sz += v[i].s;
i++;
}
i -= 1;
sz -= v[i].s;
q -= sz;
s.insert(i);
mt = max(mt, i);
printf("%lld\n", v[i].add + (ll)(q * 4));
}
printf("%lld", mt + 1);
return 0;
}
7-2 Stack of Hats (25 分)
知识点:sort
题意:
一群PATer喜欢戴帽子,进餐馆后把脱下的帽子叠起来,像一个栈,希望你指出从上到下的帽子分别是几号人的. 已知体重越大戴的帽子越大.
注意:
你需要将体重排序,帽子size排序,然后每一位就对应起来,最后对帽子的顺序重新排序,就可以了.
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
int pos;
int p;
int v;
};
bool cmp(node a, node b)
{
return a.v < b.v;
}
bool cmp2(node a, node b)
{
return a.p > b.p;
}
vector<node>v, a, v1, a1;
int main()
{
int n;
scanf("%d", &n);
v.resize(n);
a.resize(n);
for (int i = 0; i < n; ++i)
{
scanf("%d", &v[i].v);
v[i].p = i;
}
for (int i = 0; i < n; ++i)
{
scanf("%d", &a[i].v);
a[i].p = i;
}
sort(a.begin(), a.end(), cmp);
sort(v.begin(), v.end(), cmp);
for (int i = 0; i < n; ++i)
{
v[i].pos = a[i].p + 1;
}
sort(v.begin(), v.end(), cmp2);
for (int i = 0; i < n; ++i)
{
if (i != 0) printf(" ");
printf("%d", v[i].pos);
}
return 0;
}
7-3 Playground Exploration (25 分)
知识点:DFS
题意:
在操场上有很多的点,一些点之间有路径连接,小朋友可以从任意一个点进入,并且每次会选择连通点中编号最小的作为下一个目标,以及不会去一个点两次,求从哪个点进入,可以玩的点最多,如果这样的点不止一个,就输出编号最小的点,并且输出从该点出发能经过最多的点数目.
注意:
DFS就能解决,注意存储的时候记得要每个节点的连通节点通过sort实现从小到大,而且如果通过此节点进入其中一个最小没有访问子节点,就不会访问其他子节点.
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
int edge[1001][1001];
vector<int>v[10001];
int mxs = -1;
int visit[10001] = { 0 };
void dfs(int s, int sp)
{
int f = 0;
visit[s] = 1;
for (int i = 0; i < v[s].size(); ++i)
{
if (!visit[v[s][i]])
{
f = 1;
dfs(v[s][i], sp + 1);
return;
}
}
if (mxs < sp)
mxs = sp;
return;
}
int main()
{
int n, m;
scanf("%d %d", &n, &m);
for (int i = 0; i < m; ++i)
{
int x, y;
scanf("%d %d", &x, &y);
v[x].push_back(y);
v[y].push_back(x);
}
for (int i = 1; i <= n; ++i)
{
sort(v[i].begin(), v[i].end()); // 保证每个的子节点升序
}
vector<int>ans;
int mx = -1;
for (int i = 1; i <= n; ++i)
{
mxs = -1;
memset(visit, 0, sizeof(visit));
visit[i] = 1;
dfs(i, 1);
if (mx < mxs)
{
mx = mxs;
ans.clear();
ans.push_back(i);
}
else if (mx == mxs)
ans.push_back(i);
}
sort(ans.begin(), ans.end());
printf("%d %d", ans[0], mx);
return 0;
}
7-4 Sorted Cartesian Tree (30 分)
知识点:小顶堆概念建树
题意:
一棵奇奇怪怪的树,树的节点都有 { key, priority },这棵树的中序遍历按照 key 的升序排列,并且 priority 形成一个小顶堆. 要求输出这棵树的层序遍历.
注意:
这个嘛,先根据 key 排序,得到中序遍历,然后利用小顶堆的性质 - 小顶堆的根比左右子树的任意一个值都小建树获取层序遍历,具体方式就是限定左右界限,在界限内找到最小值,作为小顶堆的根,然后通过根划分左右子树,分别递归,获取层序遍历.
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
struct node
{
int k, p;
};
vector<node>v, h;
bool cmp(node a, node b)
{
if (a.k != b.k)
return a.k < b.k;
else
return a.p < b.p; // 这个意义不大,感觉没有考到这一块,应该都是不同的数字
}
vector<node>level[100];
int mmx = -1;
void build(int l, int r, int lev)
{
if (l > r) return;
int mx = v[l].p;
int t = l;
for (int i = l; i <= r; ++i)
{
if (v[i].p < mx)
{
mx = v[i].p;
t = i;
}
}
level[lev].push_back(v[t]);
mmx = max(lev, mmx);
build(l, t - 1, lev + 1);
build(t + 1, r, lev + 1);
return;
}
int main()
{
int n;
scanf("%d", &n);
v.resize(n + 1);
for (int i = 1; i <= n; ++i)
{
scanf("%d %d", &v[i].k, &v[i].p);
}
sort(v.begin() + 1, v.end(), cmp);
build(1, n, 0);
for (int i = 0; i <= mmx; ++i)
{
for (int j = 0; j < level[i].size(); ++j)
{
if (!(i == 0 && j == 0)) printf(" ");
printf("%d", level[i][j].k);
}
}
printf("\n");
for (int i = 0; i <= mmx; ++i)
{
for (int j = 0; j < level[i].size(); ++j)
{
if (!(i == 0 && j == 0)) printf(" ");
printf("%d", level[i][j].p);
}
}
return 0;
}