第六章 标准模板库
A1039. Course List for Student
A1047. Student List for Course
使用map会超时
#include <iostream>
#include <vector>
#include <algorithm>
#include <string.h>
using namespace std;
char name[40010][5];
vector<int> course[2510];
bool cmp1(int a, int b) {
return strcmp(name[a], name[b]) < 0;
}
int main() {
int n, k;
scanf("%d %d", &n, &k);
for(int i = 0; i < n; i++) {
int cnt, temp;
scanf("%s %d", name[i], &cnt);
for(int j = 0; j < cnt; j++) {
scanf("%d", &temp);
course[temp].push_back(i);
}
}
for(int i = 1; i <= k; i++) {
printf("%d %d\n", i, course[i].size());
sort(course[i].begin(), course[i].end(), cmp1);
for(int j = 0; j < course[i].size(); j++)
printf("%s\n", name[course[i][j]]);
}
return 0;
}
A1063. Set Similarity
A1060. Are They Equal
思路:把0和.全部清除掉,清除的过程中留下指数部分,剩下的字符串统计整数部分
A.1100 Mars Numbers(?)
#include <iostream>
#include <string>
using namespace std;
string a[13] = {"tret", "jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"};
string b[13] = {"####", "tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"};
string s;
int len;
void func1(int t) {
if (t / 13) cout << b[t / 13];
if ((t / 13) && (t % 13)) cout << " ";
if (t % 13 || t == 0) cout << a[t % 13];
}
void func2() {
int t1 = 0, t2 = 0;
string s1 = s.substr(0, 3), s2;
if (len > 4) s2 = s.substr(4, 3);
for (int j = 1; j <= 12; j++) {
if (s1 == a[j] || s2 == a[j]) t2 = j;
if (s1 == b[j]) t1 = j;
}
cout << t1 * 13 + t2;
}
int main() {
int n;
cin >> n;
getchar();
for (int i = 0; i < n; i++) {
getline(cin, s);
len = s.length();
if (s[0] >= '0' && s[0] <= '9')
func1(stoi(s));
else
func2();
cout << endl;
}
return 0;
}
A.1054 The Dominant Color
A.1071 Speech Patterns
A. 1022 Digital Libaray
第七章 数据结构专题
栈 A1051.Pop Sequence
模拟元素入栈,每次将1~n压入栈中,每次压完比较栈顶元素和当前出栈元素是否相等,相等则弹出栈顶元素,并将出栈元素的位置右移。依次比较。当栈中的容量超过M时,或者最后栈不为空,说明当前出栈顺序不可能。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
int arr[maxn];
stack<int> st;
int main() {
int m, n, T;
cin>> m >> n >> T;
while(T--) {
while(!st.empty()){
st.pop();
}
for (int i = 1; i <= n; i++) {
cin>>arr[i];
}
int current = 1;
bool flag = true;
for (int i = 1; i<= n; i++) {
st.push(i);
if(st.size() > m) {
flag = false;
break;
}
while(!st.empty() && st.top() == arr[current]) {
st.pop();
current++;
}
}
if(st.empty() && flag == true) {
printf("YES\n");
} else {
printf("NO\n");
}
}
return 0;
}
队列 A1056. Mice and Rice
思路:结构体mice包括排名和重量。然后设置一个队列,队列里面放入排序编号,然后每次取NG只,找出最大的再放到队列里面。依次进行直到队列只剩下一个元素。注意排名等于每次的group+1(group为组数)。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1010;
struct mouse {
int weight;
int R;
} mice[maxn];
int main() {
int np, ng, order;
cin>>np>>ng;
for (int i = 0; i < np; i++) {
cin>>mice[i].weight;
}
queue<int> q;
for (int i = 0; i < np; i++) {
cin>>order;
q.push(order);
}
int temp = np, group;
while (q.size() != 1) {
if (temp % ng == 0) group = temp / ng;
else group = temp / ng + 1;
for (int i = 0; i < group; i++) {
int k = q.front();
for (int j = 0; j < ng; j++) {
if(i * ng + j >= temp) {
break;
}
int front = q.front();
if(mice[front].weight > mice[k].weight) {
k = front;
}
mice[front].R = group + 1;
q.pop();
}
q.push(k);
}
temp = group;//下一輪老鼠总数为group
}
mice[q.front()].R = 1;
for (int i = 0; i < np; i++) {
cout<<mice[i].R;
if(i < np - 1) cout<<" ";
}
return 0;
}
A1074. 反转链表
注意细节处理就行。就是每k个进行翻转。这里用的是静态链表。因为有一些无效的节点,所以结构体需要一个字段表示是否是有效结点。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;
struct Node {
int address, data, next;
int order;//节点在链表上的序号,无效节点标记为maxn
} node[maxn];
bool cmp(Node a, Node b) {
return a.order < b.order;
}
int main() {
for (int i = 0; i < maxn; i++) {
node[i].order = maxn;
}
int begin, n, K, address;
cin>>begin>>n>>K;
for (int i = 0; i < n; i++) {
cin>>address;
cin>>node[address].data>>node[address].next;
node[address].address = address;
}
int p = begin, count = 0;
while(p != -1) {
node[p].order = count++;
p = node[p].next;
}
sort(node, node + maxn, cmp);
n = count;
for (int i = 0; i < n / K; i++) {
for(int j = (i + 1) * K - 1; j > i * K; j--) {//第i块倒着输出
printf("%05d %d %05d\n",node[j].address,node[j].data,node[j-1].address);
}
printf("%05d %d ",node[i * K].address, node[i * K].data);
if(i < n / K - 1) {//不是最后一块,就指向下一块的最后一个节点
printf("%05d\n",node[(i + 2) * K - 1].address);
} else { //是最后一块时
if(n % K == 0) { //恰好是最后一个节点
printf("-1\n");
} else {
printf("%05d\n", node[(i+1)*K].address);
for (int i = (n / K) * K; i < n; i++) {
printf("%05d %d ",node[i].address, node[i].data);
if (i < n - 1){
printf("%05d\n", node[i+1].address);
} else {
printf("-1\n");
}
}
}
}
}
return 0;
}
A1032. Sharing
求出两个链表的第一个共用节点。只需要把第一个链表每个节点存到数组里面,每个结构体增加一个flag字段表明这个节点有效(出现在第一个链表里面),然后遍历第二个链表求出第一个出现在第一个链表的节点。
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn = 100010;
struct NODE{
char data;
int next;
bool flag;//节点是否在第一条链表出现
}node[maxn];
int main() {
for (int i = 0; i < maxn; i ++ ){
node[i].flag = false;
}
int s1, s2, n;
if(scanf("%d%d%d", &s1, &s2, &n)){};
int address,next;
char data;
for (int i = 0; i < n; i ++) {
if(scanf("%d %c %d", &address, &data, &next)){};
node[address].data = data;
node[address].next = next;
}
int p;
for (p = s1; p != -1; p = node[p].next) {
node[p].flag = true;
}
for (p = s2; p != -1; p = node[p].next) {
if(node[p].flag == true) break;
}
if(p != -1){
printf("%05d\n",p);
}else{
cout<<"-1"<<endl;
}
return 0;
}
A1052. Linked List Sorting
链表排序:静态数组形式排序,只需要重写cmp方法,有效结点和无效节点比较时, 需要将有效的节点全部放在无效节点前面。有效结点和有效结点比较时,需要将值较小的放在前面。排好序顺序输出即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;
struct Node{
int address, data, next;
bool flag;
}node[maxn];
bool cmp(Node a, Node b) {
if (a.flag == false || b.flag == false) {
return a.flag > b.flag ;
} else{
return a.data < b.data;
}
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
for (int i = 0; i < maxn; i ++) {
node[i].flag = false;
}
int n, begin, address;
cin >> n >> begin;
for (int i = 0; i < n; i ++) {
cin >>address;
cin >> node[address].data >> node[address].next ;
node[address].address = address;
}
int count = 0, p =begin;
while(p != -1) {
node[p].flag = true;
count ++;
p = node[p].next;
}
if(count == 0) {
cout<<"0 -1";
} else {
sort(node,node+maxn, cmp);
printf("%d %05d\n",count,node[0].address);
for (int i = 0; i < count; i ++) {
if (i != count -1) {
printf("%05d %d %05d\n",node[i].address, node[i].data, node[i+1].address);
} else {
printf("%05d %d -1\n",node[i].address, node[i].data);
}
}
}
return 0;
}
A1097. Deduplication on a Linked List
要把绝对值相同的多余节点删了,留下第一个。那么可以定义一个数组,出现过的标记一下。然后统计留下来的节点个数和删除的节点个数。结构体一个字段order表示输出顺序。留下的节点order小,删除的节点order大。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1000010;
struct Node {
int address, data, next;
int order;
} node[maxn];
bool isExist[maxn] = {false};
bool cmp(Node a, Node b) {
return a.order < b.order;
}
int main() {
memset(isExist,false, sizeof(isExist)) ;
for (int i = 0; i < maxn; i++) {
node[i].order = 2 * maxn;
}
int n, begin, address;
cin>>begin>>n;
for (int i = 0; i < n; i++) {
cin>>address;
cin>>node[address].data>>node[address].next;
node[address].address = address;
}
int countValid = 0, countRemoved = 0, p = begin;
while (p != -1) {
if(!isExist[abs(node[p].data)]) {
isExist[abs(node[p].data)] = true;
node[p].order = countValid ++;
} else {
node[p].order = maxn + countRemoved++;
}
p = node[p].next;
}
sort(node, node + maxn, cmp);
int count = countValid + countRemoved;
for (int i = 0; i < count; i++) {
if (i != countValid - 1 && i != count -1) {
printf("%05d %d %05d\n", node[i].address,node[i].data,node[i+1].address);
} else {
printf("%05d %d -1\n", node[i].address,node[i].data);
}
}
return 0;
}
第八章 搜索专题
DFS A1103 Integer Factorization
首先:用一个数组将候选的数全部存起来。fac[i] = i^p。DFS用于从fac选择若干个数。
DFS参数有:①当前处理到的fac的第几个数,②已经选择了几个数nowK③当前选择的数的和④当前选择出的最小底数和
为了获取字典序最大的序列,让index从大到小进行遍历就行。
#include<bits/stdc++.h>
using namespace std;
int n, k, p, maxFacSum = -1;
vector<int> fac, ans, temp;
int power(int x) {
int ans = 1;
for(int i = 0; i < p; i++) {
ans *= x;
}
return ans;
}
void init(){
int i = 0;
int temp = 0;
while(temp <= n) {
fac.push_back(temp);
temp = power(++i);
}
}
void DFS(int index, int nowK, int sum, int facSum){
if(sum == n && nowK == k) {
if(facSum > maxFacSum ) {
ans = temp;
maxFacSum = facSum;
}
return ;
}
if(sum > n || nowK > k) return;
if(index - 1 >= 0) {//fac[0]不用选择
temp.push_back(index);
DFS(index,nowK+1,sum+fac[index],facSum+index);//选
temp.pop_back();
DFS(index - 1,nowK,sum,facSum);//不选
}
}
int main(){
cin>>n>>k>>p;
init();
DFS(fac.size()-1,0,0,0);
if(maxFacSum == -1) printf("Impossible\n");
else{
printf("%d = %d^%d",n,ans[0],p);
for(int i = 1;i < ans.size(); i++) {
printf(" + %d^%d",ans[i],p);
}
}
}
BFS A1091. Acute Stroke
一个三维空间的块统计而已,换汤不换药。看懂题目才难。
#include<bits/stdc++.h>
using namespace std;
struct node{
int x, y, z;
} Node;
int n, m, slice1, T;
int pixel[1290][130][61];//三维矩阵
bool inq[1290][130][61] = {false};
int X[6] ={0,0,0,0,1,-1};
int Y[6] ={0,0,1,-1,0,0};
int Z[6] ={1,-1,0,0,0,0};
bool judge(int x, int y, int z) {
if(x >= n || x < 0 || y >= m || y < 0 || z >= slice1 || z < 0) return false;
if(pixel[x][y][z] == 0 || inq[x][y][z] == true) return false;
return true;
}
int BFS(int x, int y, int z) {
int tot = 0;
queue<node> Q;
Node.x = x, Node.y = y, Node.z = z;
Q.push(Node);
inq[x][y][z] = true;
while(!Q.empty()) {
node top = Q.front();
Q.pop();
tot ++;
for(int i = 0; i < 6; i++) {
int newX = top.x + X[i];
int newY = top.y + Y[i];
int newZ = top.z + Z[i];
if(judge(newX, newY, newZ)) {
Node.x = newX, Node.y = newY, Node.z = newZ;
Q.push(Node);
inq[newX][newY][newZ] = true;
}
}
}
if(tot >= T) return tot;
else return 0;
}
int main() {
if(scanf("%d%d%d%d",&n,&m,&slice1,&T)){};
for(int z = 0; z < slice1; z++) {
for(int x = 0; x < n; x++) {
for (int y = 0; y < m; y++) {
if(scanf("%d",&pixel[x][y][z])){};
}
}
}
int ans = 0;
for(int z = 0; z < slice1; z++) {
for(int x = 0; x < n; x++) {
for (int y = 0; y < m; y++) {
if(pixel[x][y][z] == 1 && inq[x][y][z] == false){
ans += BFS(x,y,z);
}
}
}
}
cout<<ans<<endl;
return 0;
}
第九章 数据结构专题(2)
二叉树 A1020. Tree Traversals
根据中序和后序构造前序,然后层序遍历
#include<bits/stdc++.h>
using namespace std;
struct node {
int data;
node* lchild;
node* rchild;
};
const int maxn = 50;
int pre[maxn], in[maxn], post[maxn];
int n;
node* create(int postL,int postR, int inL, int inR) {
if(postL > postR) return NULL;
node* root = new node;
root->data = post[postR];
int k;
for(k = inL; k <= inR; k++) {
if(in[k] == post[postR]) {
break;
}
}
int numLeft = k - inL;
root->lchild = create(postL, postL + numLeft - 1,inL, k - 1);
root->rchild = create(postL + numLeft, postR - 1, k + 1, inR);
return root;
}
int num = 0;
void BFS(node* root) {
queue<node*> q;
q.push(root);
while(!q.empty()) {
node* now = q.front();
q.pop();
cout<<now->data;
num ++;
if(num < n) cout<<" ";
if(now->lchild != NULL) q.push(now->lchild);
if(now->rchild != NULL) q.push(now->rchild);
}
}
int main(){
cin>>n;
for (int i = 0; i < n; i ++) {
cin>>post[i];
}
for (int i = 0; i < n; i ++) {
cin>>in[i];
}
node* root = create(0, n - 1, 0, n - 1);
BFS(root);
return 0;
}
A1086. Tree Traversals Again
根据先序和中序求后序,换汤不换药
A1102. Invert a Binary Tree
反转:后序遍历递归写法:先反转叶子节点,再往上反转。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 110;
struct node {
int lchild, rchild;
} Node[maxn];
bool notRoot[maxn] = {false};//记录师傅不是根节点,初始时刻均是根节点
int n, num = 0;//n为节点个数,num为已经输出的节点个数
void print(int id) {
printf("%d",id);
num ++;
if(num < n) printf(" ");
else printf("\n");
}
void inOrder(int root) {//中序遍历
if(root == -1) return;
inOrder(Node[root].lchild);
print(root);
inOrder(Node[root].rchild);
}
void BFS(int root) {
queue<int> q;
q.push(root);
while(!q.empty()) {
int now = q.front();
q.pop();
print(now);
if(Node[now].lchild != -1) q.push(Node[now].lchild);
if(Node[now].rchild != -1) q.push(Node[now].rchild);
}
}
//后序遍历,用以反转二叉树
void postOrder(int root) {
if (root == -1) return ;
postOrder(Node[root].lchild);
postOrder(Node[root].rchild);
swap(Node[root].lchild,Node[root].rchild);
}
int strToNum(char c) {
if(c == '-') return -1;
else {
notRoot[c - '0'] = true;
return c - '0';
}
}
int findRoot() {
for (int i = 0; i < n; i++) {
if(notRoot[i] == false){
return i;
}
}
return -1;
}
int main() {
char lchild, rchild;
cin>>n;
for(int i = 0; i < n; i++) {
cin>>lchild>>rchild;
Node[i].lchild = strToNum(lchild);
Node[i].rchild = strToNum(rchild);
}
int root = findRoot();
postOrder(root);
BFS(root);
num = 0;
inOrder(root);
return 0;
}
树的遍历 A1079 Total Sales of Supply Chain
题意:给出一棵销售供应的树,树根唯一。树根处货物的价格为P,然后从树根节点每往子节点走一层,该层的货物价格会在父节点的价格上增加r%,给出每个叶节点的货物量,求他们的价格之和。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;
struct node {
double data;
vector<int> child;//指针域
} Node[maxn];
int n;
double p, r, ans = 0;
void DFS(int index, int depth) {
if(Node[index].child.size() == 0) {
ans += Node[index].data * pow(1 + r, depth);
return;
}
for (unsigned int i = 0; i < Node[index].child.size(); i++){
DFS(Node[index].child[i], depth + 1);
}
}
int main() {
int k, child;
if(scanf("%d%lf%lf",&n,&p,&r)){};
r /= 100;
for(int i = 0; i < n; i++) {
if(scanf("%d",&k)){};
if(k == 0) {
if(scanf("%lf",&Node[i].data)){};
} else {
for (int j = 0; j < k; j++) {
if(scanf("%d",&child)){};
Node[i].child.push_back(child);
}
}
}
DFS(0,0);
printf("%.1f\n",p*ans);
return 0;
}
A1090 Highest Price in Supply Chain
#include<bits/stdc++.h>
using namespace std;
const int maxn = 100010;
vector<int> child[maxn];
int n;
double p, r, ans = 0;
int num = 0, maxDepth = 0;
void DFS(int index, int depth) {
if(child[index].size() == 0) {
if(depth > maxDepth) {
maxDepth = depth;
num = 1;
} else if(depth == maxDepth) {
num ++;
}
return;
}
for (unsigned int i = 0; i < child[index].size(); i++) {
DFS(child[index][i], depth + 1);
}
}
int main() {
int father, root;
if(scanf("%d%lf%lf", &n, &p, &r)){};
r /= 100;
for(int i = 0; i < n; i++) {
if(scanf("%d",&father)){};
if(father != -1) {
child[father].push_back(i);
} else {
root = i;
}
}
DFS(root,0);
printf("%.2f %d\n", p * pow(1 + r,maxDepth), num);
return 0;
}
A1094 The Largest Generation
题意:求节点个数最多的一层,并且输出节点个数和层号
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 110;
vector<int> Node[MAXN];
int hashTable[MAXN] ={0};
void DFS(int index, int level) {
hashTable[level] ++;
for (unsigned int j = 0; j < Node[index].size(); j++) {
DFS(Node[index][j], level + 1);
}
}
int main() {
int n, m, parent, k, child;
if(scanf("%d%d",&n,&m)){};
for (int i = 0; i < m; i++) {
if(scanf("%d%d",&parent,&k)){};
for (int j = 0; j < k; j++) {
if(scanf("%d",&child)){};
Node[parent].push_back(child);
}
}
DFS(1,1);
int maxLevel = -1, maxValue = 0;
for(int i = 1; i < MAXN; i++) {
if(hashTable[i] > maxValue) {
maxValue = hashTable[i];
maxLevel = i;
}
}
printf("%d %d\n",maxValue,maxLevel);
return 0;
}
A1106 Lowest Price in Supply Chain (25 分)
A1104 Sum of Number Segments (20 分)
A1053 Path of Equal Weight (30 分)
二叉查找树 A1043 Is It a Binary Search Tree (25 分)
struct node {
int data;
node* left, *right;
};
void insert(node* &root, int data) {
if(root == NULL) {
root = new node;
root->data = data;
root->left = root->right = NULL;
return;
}
if(data < root->data) {
insert(root->left,data)
}
else {
insert(root->right,data);
}
}
void preOrder(node* root, vector<int>& vi) {
if(root == NULL) {
return;
}
vi.push_back(root->data);
preOrder(root->left,vi);
preOrder(root->right,vi);
}
void preOrderMirror(node* root, vector<int>& vi) {
if(root == NULL) return;
vi.push_back(root->data);
preOrderMirror(root->right);
preOrderMirror(root->left);
}
void postOrder(node* root, vector<int>& vi) {
if(root == NULL) {
return;
}
postOrder(root->left,vi);
vi.push_back(root->data);
postOrder(root->right,vi);
}
void postOrderMirror(node* root, vector<int>& vi) {
if(root == NULL) return;
postOrderMirror(root->right);
vi.push_back(root->data);
postOrderMirror(root->left);
}