1091 Acute Stroke (30 分)
数三维数组的连通块,并计算块大小大于等于t的体积之和
dfs和bfs都写了,但是dfs会爆栈的,所以迷宫类问题还是bfs吧,时间复杂度应该差不多
#include<bits/stdc++.h>
using namespace std;
bool matrix[1300][130][65], vis[1300][130][65];
int X[8] = {0, 0, 1, -1, 0, 0};
int Y[8] = {1, -1, 0, 0, 0, 0};
int Z[8] = {0, 0, 0, 0, -1, 1};
int m, n, l, t;
//三维数组的bfs和dfs,应该会都写一下
struct node{
int x, y, z;
};
bool judge(int x, int y, int z) {
if(x < 0 || x > m-1 || y < 0 || z < 0 || y > n-1 || z > l-1) return false;
if(vis[x][y][z] || !matrix[x][y][z]) return false;
return true;
}
int dfs(int x, int y, int z) {
vis[x][y][z] = 1;
int vol = 1;
for(int i = 0; i < 6; i++) {//6个方向
int nx = x + X[i], ny = y + Y[i], nz = z + Z[i];
if(judge(nx, ny, nz)){
vol += dfs(nx, ny, nz);
}
}
return vol;
}
int bfs(int x, int y, int z) {
queue<node> q;
node s = {x,y,z};
q.push(s);
vis[x][y][z] = 1;
int vol = 1;
while(q.size()) {
node now = q.front();
q.pop();
for(int i = 0; i < 6; i++) {//6个方向
int nx = now.x + X[i], ny = now.y + Y[i], nz = now.z + Z[i];
if(judge(nx, ny, nz)){
vol ++;
vis[nx][ny][nz] = 1;
q.push({nx, ny, nz});
}
}
}
return vol;
}
int main() {
scanf("%d %d %d %d",&m,&n,&l,&t);
//m行n列k层
for(int k = 0; k < l; k++) {
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
scanf("%d",&matrix[i][j][k]);
}
}
}
int total = 0;
for(int k = 0; k < l; k++) {
for(int i = 0; i < m; i++) {
for(int j = 0; j < n; j++) {
if(!vis[i][j][k] && matrix[i][j][k]) {
int tem = bfs(i, j, k);
if(tem >= t)total += tem;
}
}
}
}
printf("%d\n",total);
return 0;
}
1092 To Buy or Not to Buy (20 分)
记录第二个串中的字母是否都在第一个串中出现(数量需考虑)
#include<bits/stdc++.h>
using namespace std;
int cnt[300];
int main() {
string a, b;
cin >> a >> b;
for(int i = 0; i < a.length(); i++) {
cnt[a[i]]++;
}
int l = b.length(), sh = 0;
for(int i = 0; i < b.length(); i++) {
if(cnt[b[i]] > 0) cnt[b[i]]--, l--;
else {
sh++;
}
}
if(l) printf("No %d",sh);
else printf("Yes %d",a.length() - b.length());
return 0;
}
1093 Count PAT’s (25 分)
遍历一遍字符串,记录A的位置,和初始位置到每个位置上P和T的数量,然后遍历一遍A的位置,每次答案加上A前面P的个数*后面T的数量
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
const int mod = 1e9 + 7;
int pnum[N], tnum[N];
vector<int> pos;
#define ll long long
int main() {
char ch;
int p = 0;
while(cin >> ch) {
pnum[++p] = pnum[p-1];
tnum[p] = tnum[p-1];
if(ch == 'P') pnum[p]++;
else if(ch == 'A') pos.push_back(p);
else if(ch == 'T') tnum[p] ++;
}
ll ans = 0;
for(int i = 0; i < pos.size(); i++) {
int j = pos[i];
ans = (ans + pnum[j] * (tnum[p] - tnum[j])) % mod;
}
cout<<ans<<endl;
return 0;
}
1094 The Largest Generation (25 分)
bfs,dfs都可以,数据量很小无所谓,找结点数最多的一层,并输出数量和所在层
#include<bits/stdc++.h>
using namespace std;
vector<int> v[105];
int num[105], depth[105], ma, gene;
void dfs(int x) {
for(int i = 0; i < v[x].size(); i++) {
int y = v[x][i];
depth[y] = depth[x] + 1;
num[depth[y]]++;
if(num[depth[y]] > ma) {
ma = num[depth[y]];
gene = depth[y];
}
dfs(y);
}
}
int main() {
int n, m, p, k, kid;
scanf("%d %d",&n, &m);
for(int i = 0; i < m; i++) {
scanf("%d %d",&p, &k);
while(k--) {
scanf("%d",&kid);
v[p].push_back(kid);
}
}
ma = depth[1] = 1;
gene = num[1] = 1;
dfs(1);
printf("%d %d",ma, gene);
return 0;
}
/*
23 13
21 1 23
01 4 03 02 04 05
03 3 06 07 08
06 2 12 13
13 1 21
08 2 15 16
02 2 09 10
11 2 19 20
17 1 22
05 1 11
07 1 14
09 1 17
10 1 18
3 1
1 2 2 3
*/
1095 Cars on Campus (30 分)
这道题前面有个类似的去银行处理事务的题,但是这题感觉更复杂,因为有一个查询
查询处理
这个查询显然线性查应该是会超时的(没试,我也不知道),所以用了内置的upper_bound函数进行二分查找,就是把合法的时间段(in和out成功配对)分别加入一个in数组,一个out数组,(我做了个简单测试,应该还是数组排序更快,但这里用vector也没有超时,应该数据量不算太大)然后分别查找到现在时间所在的位置,已经进去的车的数量-已经出来的车的数量=当前停车数
vector和数组的测试
#include<bits/stdc++.h>
using namespace std;
const int N = 5e6 + 5;
int arr[N];
vector<int> a;
int main()
{
int n = 5e6;
mt19937 rand_num(unsigned(time(0)));
uniform_int_distribution<long long> dist(1, 1000000);
for(int i = 0; i < n; i++) {
int t = dist(rand_num);
arr[i] = t;
a.push_back(t);
}
clock_t st1, st2, ed1, ed2;
st1 = clock();
sort(arr, arr+n);
ed1 = clock();
st2 = clock();
sort(a.begin(), a.end());
ed2 = clock();
cout<< "Run1: "<<(int)(ed1-st1)*1000 / CLOCKS_PER_SEC << "ms" <<endl;
cout<< "Run2: "<<(int)(ed2-st2)*1000 / CLOCKS_PER_SEC << "ms" <<endl;
return 0;
}
其他处理
1.时间读入的时候可以根据格式直接读入时分秒,然后全部转换成秒,后面处理起来也会更方便
2.注意是否合法数据的处理,遇到in直接向后即可,遇到out判断前面是不是in,是in才是合法的,其他情况都不合法
#include<bits/stdc++.h>
using namespace std;
struct record{
int time;
bool f;
friend bool operator< (record a, record b) {
return a.time < b.time;
}
};
unordered_map<string, vector<record> >mp;
unordered_map<string, int> per;
set<string> name;
vector<int> in, out;
int cal(int h, int m, int s){
return 3600*h + 60*m + s;
}
int main() {
int n, k, h, m, s, maxt = -1;
scanf("%d %d",&n,&k);
string a,b;
a.resize(7);
b.resize(2);
record r;
for(int i = 0; i < n; i++) {
scanf("%s %2d:%2d:%2d %s",&a[0],&h,&m,&s,&b[0]);
r.time = cal(h, m, s);
if(b == "in") r.f = 0;
else r.f = 1;
// printf("%s %02d:%02d:%02d %d\n",a.c_str(),r.h,r.m,r.s,r.f);
mp[a].push_back(r);
}
for(auto it: mp) {
a = it.first;
sort(mp[a].begin(), mp[a].end());
int l = mp[a].size();
r.f = 1;
for(int i = 0; i < l; i++) {
if(mp[a][i].f == 1) {//遇到out判断是不是合法数据
if(r.f == 0) {//配上了
in.push_back(r.time);
out.push_back(mp[a][i].time);
int pt = mp[a][i].time - r.time;
per[a] += pt;
if(maxt < per[a]) {
maxt = per[a];
name.clear();
name.insert(a);
}
else if(maxt == per[a]) {
name.insert(a);
}
}
}
r = mp[a][i];//遇到in直接向下
}
}
sort(in.begin(), in.end());
sort(out.begin(), out.end());
for(int i = 0; i < k; i++) {
scanf("%2d:%2d:%2d",&h,&m,&s);
int nowt = cal(h, m, s);
int p1 = upper_bound(in.begin(), in.end(), nowt) - in.begin();
int p2 = upper_bound(out.begin(), out.end(), nowt) - out.begin();
printf("%d\n",p1-p2);
}
for(auto it: name) {
cout<<it<<" ";
}
h = maxt/3600;
m = (maxt%3600) / 60;
s = (maxt%3600) % 60;
printf("%02d:%02d:%02d\n",h,m,s);
return 0;
}
1096 Consecutive Factors (20 分)
一开始我的写法是下面这种,肯定是错的很离谱啊,但是也有18分。。。。比如6720明明答案应该是{4,5,6,7,8}但是我试过{2,3,4,5}之后不会再回头了就会出现错误,所以必须还是得用循环嵌套的,一次遍历得答案是不可能的
还有最后两个测试点是质数,比如2,2147483647这种,质数也处理正确即可
for(int i = 2; i <= sqrt(n); i++ ) {
if(t % i) {
if(tnum > num) {
num = tnum;
ans = tem;
}
tem.clear();
tnum = 0;
t = n;
}
else {
tnum++;
t /= i;
tem.push_back(i);
}
}
#include<bits/stdc++.h>
using namespace std;
int main() {
int n, t, x, tnum = 0, num = 0, st;
scanf("%d",&n);
for(int i = 2; i <= sqrt(n)+1; i++ ) {
x = i;
t = n;
tnum = 0;
while(t % x == 0) {
tnum++;
t /= x;
x++;
}
if(tnum > num) {
num = tnum;
st = i;
}
}
if(num == 0) {
printf("1\n%d",n);
}
else {
cout<<num<<endl;
for(int i = 0; i < num; i++) {
if(i) printf("*");
printf("%d",i + st);
}
}
return 0;
}
1097 Deduplication on a Linked List (25 分)
这题测试点2的坑在于给定的链表中没有需要删除的元素
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5;
int L1[N], L2[N], val[N], nxt[N];
bool v[N];
int main() {
int head, n, th, tn, t;
scanf("%d %d",&head, &n);
for(int i = 0; i < n; i++) {
scanf("%d %d %d",&th, &t, &tn);
nxt[th] = tn;
val[th] = t;
}
int now = head, p = 0, q = 0;
for(int i = 0; i < n; i++) {
if(now == -1) break;
int data = abs(val[now]);
if(v[data]) L2[q++] = now;//已经访问过了
else L1[p++] = now, v[data] = 1;
now = nxt[now];
}
for(int i = 0; i < p-1; i++) {
printf("%05d %d %05d\n", L1[i], val[L1[i]], L1[i+1]);
}
if(p) printf("%05d %d -1\n", L1[p-1], val[L1[p-1]]);
for(int i = 0; i < q-1; i++) {
printf("%05d %d %05d\n", L2[i], val[L2[i]], L2[i+1]);
}
if(q) printf("%05d %d -1\n", L2[q-1], val[L2[q-1]]);
return 0;
}
1098 Insertion or Heap Sort (25 分)
1089和1098这两题可以充分背一下归并排序和堆排序
#include<bits/stdc++.h>
using namespace std;
int ori[105], des[105], n;
bool check() {
for(int i = 0; i < n; i++) {
if(ori[i+1] != des[i]) return false;
}
return true;
}
void shift_down(int i, int n) {
while(i*2 <= n) {
i *= 2;
if(i+1 <= n && ori[i] < ori[i+1]) i++;
if(ori[i] > ori[i/2]) swap(ori[i], ori[i/2]);
else return;
}
}
void create() {
for(int i = n/2; i >= 1; i--) {
shift_down(i, n);
}
}
int main() {
scanf("%d", &n);
for(int i = 1; i <= n; i++) scanf("%d", ori+i);
for(int i = 0; i < n; i++) scanf("%d", des+i);
bool f = 0;
create();
for(int i = n; i > 1; i--) {
swap(ori[i], ori[1]);
shift_down(1, i-1);
if(f) {
printf("Heap Sort\n");
for(int i = 1; i <= n; i++) {
if(i != 1) printf(" ");
printf("%d", ori[i]);
}
return 0;
}
if(check()) f = 1;
}
printf("Insertion Sort\n");
for(int i = 1; i < n; i++) {
if(des[i] < des[i-1]) {
int tem = des[i], j = i;
for(; des[j-1] > tem; j-- ) {
des[j] = des[j-1];
}
des[j] = tem;
break;
}
}
for(int i = 0; i < n; i++) {
if(i) printf(" ");
printf("%d",des[i]);
}
return 0;
}
1099 Build A Binary Search Tree (30 分)
首先给定树的结构,然后给一个序列,对BST进行中序遍历的结果就是一个有序的序列,所以对前面给定的序列排序之后,中序遍历一遍把所有元素赋上值,再层次遍历一遍即可
#include<bits/stdc++.h>
using namespace std;
int arr[105], cnt;
vector<int> ans;
struct node{
int val, l, r;
}v[105];
void inorder(int root) {
if(root == -1) return;
inorder(v[root].l);
v[root].val = arr[cnt++];
inorder(v[root].r);
}
void levelorder() {
queue<node> q;
q.push(v[0]);
while(q.size()) {
node now = q.front();
q.pop();
ans.push_back(now.val);
if(now.l != -1) q.push(v[now.l]);
if(now.r != -1) q.push(v[now.r]);
}
}
int main() {
int n, l, r;
scanf("%d",&n);
for(int i = 0; i < n; i++) {
scanf("%d %d",&l,&r);
v[i].l = l, v[i].r = r;
}
for(int i = 0; i < n; i++) scanf("%d",arr+i);
sort(arr, arr+n);//中序
inorder(0);
levelorder();
for(int i = 0; i < ans.size(); i++) {
if(i) printf(" ");
printf("%d",ans[i]);
}
return 0;
}
1100 Mars Numbers (20 分)
一个奇奇怪怪的题,如果是26并不是hel tret而是hel,注意这一点就没什么了
#include<bits/stdc++.h>
using namespace std;
string ge[20] = {"tret","jan", "feb", "mar", "apr", "may", "jun", "jly", "aug", "sep", "oct", "nov", "dec"};
string shi[20] = {"","tam", "hel", "maa", "huh", "tou", "kes", "hei", "elo", "syy", "lok", "mer", "jou"};
void mars(string s) {//阿拉伯到火星数
int n, d1, d2;
stringstream ss;
ss << s;
ss >> n;
d1 = n % 13, d2 = n / 13;
if(d2) {
if(d1)printf("%s %s\n",shi[d2].c_str(), ge[d1].c_str());
else printf("%s\n",shi[d2].c_str());
}
else printf("%s\n",ge[d1].c_str());
}
void earth(string s) {//火星数到阿拉伯数字
int p = s.find(" "), l = s.length();
string d1, d2;
if(p != string::npos) {
d1 = s.substr(0, p);
d2 = s.substr(p+1, l);
}
else {
d1 = "";
d2 = s;
}
int ans = 0;
if(!d1.empty()) {
for(int i = 0; i < 13; i++) {
if(shi[i] == d1) {
ans += i*13;
break;
}
}
for(int i = 0; i < 13; i++) {
if(ge[i] == d2) {
ans += i;
break;
}
}
printf("%d\n", ans);
}
else{
for(int i = 0; i < 13; i++) {
if(ge[i] == d2) {
printf("%d\n",i);
return;
}
}
for(int i = 1; i < 13; i++) {
if(shi[i] == d2) {
printf("%d\n",i*13);
}
}
}
}
int main() {
int n;
scanf("%d", &n);
getchar();
string t;
for(int i = 0; i < n; i++) {
getline(cin , t);
if(isdigit(t[0])){
mars(t);
}
else {
earth(t);
}
}
return 0;
}