7-1 Good in C (20分)
读题比较麻烦,实际不难,注意输出格式就可以了。
#include<cstdio>
#include<vector>
#include<iostream>
#include<queue>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
vector<vector<string> > vab;
vector<string> ca;
string str, temp;
int main() {
for (int i = 0; i < 26; i++) {
ca.clear();
for (int j = 0; j < 7; j++) {
cin >> str;
ca.push_back(str);
}
vab.push_back(ca);
}
getchar();
getline(cin, str);
temp = {};
ca.clear();
for (int i = 0; i < str.size(); i++) {
if (str[i] >= 'A' && str[i] <= 'Z') {
temp += str[i];
}
else if (temp.size() != 0) {
ca.push_back(temp);
temp.clear();
}
}
if (temp.size() != 0) {
ca.push_back(temp);
}
for (int i = 0; i < ca.size(); i++) {
for (int col = 0; col < 7; col++) {
for (int j = 0; j < ca[i].size(); j++) {
int t = ca[i][j] - 'A';
cout << vab[t][col];
if (j != ca[i].size() - 1) printf(" ");
else printf("\n");
}
}
if (i != ca.size() - 1) printf("\n");
}
return 0;
}
7-2 Block Reversing (25分)
静态数组,多做就不难。
#include<cstdio>
#include<vector>
#include<iostream>
#include<queue>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
#define maxn 100100
struct node {
int data, address, block, inside;
node(int d, int a, int b, int i) : data(d), address(a), block(b), inside(i) {}
bool operator < (const node &a) const {
if (a.block != block) return block > a.block;
else return inside < a.inside;
}
};
int N, K, firstaddress;
int data[maxn], nest[maxn];
vector<node> v;
int main() {
scanf("%d %d %d", &firstaddress, &N, &K);
int a, b, c;
for (int i = 0; i < N; i++) {
scanf("%d %d %d", &a, &b, &c);
data[a] = b;
nest[a] = c;
}
int ta = firstaddress;
int blockcount = 0, insidecount = 0;
while(ta != -1) {
v.push_back(node(data[ta], ta, blockcount, insidecount));
insidecount++;
if (insidecount == K) {
insidecount = 0;
blockcount++;
}
ta = nest[ta];
}
sort(v.begin(), v.end());
for (int i = 0; i < v.size(); i++) {
if (i != v.size() - 1) printf("%05d %d %05d\n", v[i].address, v[i].data, v[i + 1].address);
else printf("%05d %d -1\n", v[i].address, v[i].data);
}
return 0;
}
7-3 Summit (25分)
将每个area的邻近结点都放入temp中存储,采用set存储,以确保所有的结点只出现一次。
然后,对area的每一个结点,将temp中不存在于他的邻近结点中的删除。得到一个包含area所有结点的最小连通图(不太确定名词对不对,但是就是题目所说的最佳安排)。
将最佳安排temp和area进行比较就可以输出了。
注意:
temp中需要加入area所有结点,否则有一些结点只有单一个就会出错。
temp中删除结点时,不删除检查的当前结点,否则导致错误。
#include<cstdio>
#include<vector>
#include<iostream>
#include<queue>
#include<cmath>
#include<string>
#include<algorithm>
#include<set>
using namespace std;
#define maxn 205
set<int> g[maxn];
int N, M, K, L;
set<int> area, temp;
set<int>::iterator it, jt;
int main() {
scanf("%d %d", &N, &M);
int a, b;
while(M--) {
scanf("%d %d", &a, &b);
g[a].insert(b);
g[b].insert(a);
}
scanf("%d", &K);
for (int i = 0; i < K; i++) {
area.clear();
temp.clear();
scanf("%d", &L);
while(L--) {
scanf("%d", &a);
area.insert(a);
temp.insert(a);
for (it = g[a].begin(); it != g[a].end(); it++) {
temp.insert(*it);
}
}
for (it = area.begin(); it != area.end(); it++) {
vector<int> v;
for (jt = temp.begin(); jt != temp.end(); jt++) {
int t = *jt;
if (t == *it) continue;
if (0 == g[*it].count(*jt)) v.push_back(*jt);
}
for (int k = 0; k < v.size(); k++) {
temp.erase(v[k]);
}
}
if (temp == area) {
printf("Area %d is OK.\n", i + 1);
}
else if (temp.size() > area.size()) {
printf("Area %d may invite more people, such as ", i + 1);
for (it = temp.begin(); it != temp.end(); it++) {
if (area.count(*it) == 0) {
printf("%d.\n", *it);
break;
}
}
}
else printf("Area %d needs help.\n", i + 1);
}
return 0;
}
7-4 Cartesian Tree (30分)
咋一看很麻烦,其实很简单。
就是将每个区域的最小点作为根,然后根据这个点分成两个区域,再在每个区域重复当前步骤。
上面得到一棵树,接着层次遍历,搞定。
#include<cstdio>
#include<vector>
#include<iostream>
#include<queue>
#include<cmath>
#include<string>
#include<algorithm>
#include<set>
using namespace std;
vector<int> input, out;
struct node {
int data;
node *left, *right;
};
node* build(int left, int right) {
if (left >= right) return NULL;
node* root = new node;
int minone = left, i;
for (i = left + 1; i < right; i++) {
if (input[i] < input[minone]) minone = i;
}
root->data = input[minone];
root->left = build(left, minone);
root->right = build(minone + 1, right);
return root;
}
void level(node *root) {
queue<node*> q;
q.push(root);
while(!q.empty()) {
node* temp = q.front();
q.pop();
out.push_back(temp->data);
if (temp->left != NULL) q.push(temp->left);
if (temp->right != NULL) q.push(temp->right);
}
return;
}
int main() {
int a, N;
scanf("%d", &N);
for (int i = 0; i < N; i++) {
scanf("%d", &a);
input.push_back(a);
}
node *root = build(0, N);
level(root);
for (int i = 0; i < N; i++) {
printf("%d", out[i]);
if (i != N - 1) printf(" ");
else printf("\n");
}
return 0;
}
总结
这次的题目个人感觉没有特别多的思考量,都是比较基础的应用,而且没有什么坑,这是最难得的。