SMU 2024 spring 天梯赛2
7-1计算指数
gogogo
查看代码
void solve() {
int n;
cin >> n;
cout << "2^" << n << " = " << (int)pow(2, n);
}
7-2计算摄氏温度
good
查看代码
void solve() {
int f = 100;
int c = 5 * (f - 32) / 9;
cout << "fahr = " << f << ", celsius = " << c;
}
7-3念数字
go notbad
查看代码
void solve() {
vector<string > ve(10);
ve[0] = "ling", ve[1] = "yi", ve[2] = "er", ve[3] = "san", ve[4] = "si",
ve[5] = "wu", ve[6] = "liu", ve[7] = "qi", ve[8] = "ba", ve[9] = "jiu";
string s;
cin >> s;
for (int i = 0; i < s.size(); ++i) {
if (s[i] == '-') cout << "fu";
else cout << ve[s[i] - '0'];
if (i < s.size() - 1) cout << ' ';
}
}
7-4求阶乘累加和
gooood
查看代码
void solve() {
int n, sum = 0;
cin >> n;
for (int i = 1, p = 1; i <= n; ++i) {
p *= i;
sum += p;
}
cout << sum;
}
7-56翻了
思路:找出所有连续的6,用replace来替换
查看代码
void solve() {
string s;
getline(cin, s);
for (int i = 0; i < s.size(); ++i) {
if (s[i] == '6') {
int j = i;
while (j + 1 < s.size() && s[j + 1] == '6') {
j ++;
}
if (j - i + 1 > 9) {
s.replace(i, j - i + 1, "27");
} else if (j - i + 1 > 3) {
s.replace(i, j - i + 1, "9");
}
}
}
cout << s << '\n';
}
7-6福到了
notbad
思路:用reverse来置换
查看代码
void solve() {
char op;
int n;
cin >> op >> n;getchar();
vector<string > ve(n), t(n);
for (int i = 0; i < n; ++i) {
getline(cin, ve[i]);
t[i] = ve[i];
std::reverse(t[i].begin(), t[i].end());
}
bool ok = true;
for (int i = 0, j = n - 1; i < n; ++i, --j) {
if (ve[i] != t[j]) {
ok = false;
break;
}
}
if (ok) cout << "bu yong dao le\n";
for (int i = n - 1; i >= 0; --i) {
for (int j = 0; j < n; ++j) {
if (t[i][j] == '@') cout << op;
else cout << ' ';
}
cout << '\n';
}
}
7-7估值一亿的AI核心代码
ohhhhhno what
思路:需要注意一点,出现了you can 或 you could 后,you会变成 I ,而这个 I 不能再转换成 you
接下来就是狠狠模拟,可以将所有字符分段,保证每段的属性相同(字母,数字,符号,空格)
对串进行删减:
对于为字母的段,保证除了 I 以外全为小写
对于为数字的段,不用改变
对于为符号的段,不用改变
对于为空格的段,长度最长为1, 若其后面一段为符号,忽略掉该段空格
对串进行替换:
找到 can you 和 could you 后(注意中间有个空格段),将 空格段 和 you 删掉, 保存 I + 空格 + can 或 I + 空格 + could,这个时候将保存的这一段存成一段,如此一来,在将 I 替换成 you 这一操作时,不会再将转换后的 I can 或 I could 的 I 再次操作
最后就是逐个判断每个段是否是 I 或 me,将所有 ?换成 !
end
查看代码
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;
int f( char x ){
if( x == ' ' ) return 0;
if( x >= 'a' and x <= 'z' || x >= 'A' and x <= 'Z' ) return 1;
if( x >= '0' and x <= '9' ) return 3;
return 4;
}
void solve() {
int n;
cin >> n;
getchar();
auto toa = [](char c) {
if (c == 'I') return c;
if (c >= 'A' && c <= 'Z') return (char)(c + 32);
return c;
};
auto check = [toa](string s) {
vector<string> ve;
string t;
for ( int i = 0; i < s.size(); ++i) {
if (t.empty() || f(s[i]) == f (s[i - 1])) {
t.push_back(toa(s[i]));
} else {
ve.push_back(t);
t.clear();
t.push_back(toa(s[i]));
}
}
if (!t.empty()) ve.push_back(t);
while (!ve.empty() && ve.begin()->front() == ' ') ve.erase(ve.begin());
while (!ve.empty() && ve.back().front() == ' ') ve.pop_back();
vector<string > g;
for (int i = 0; i < ve.size(); ++i) {
if (ve[i].front() == ' ' && i + 1 < ve.size() && f(ve[i + 1].front()) == 4)continue;
if (ve[i].front() == ' ' && ve[i].size() > 1) ve[i] = " ", g.push_back(ve[i]);
else {
if (f(ve[i].front()) == 4) {
for (int j = 0; j < ve[i].size(); ++j) {
if (ve[i][j] == '?') ve[i][j] = '!';
}
}
g.push_back(ve[i]);
}
}
ve.swap(g);
g.clear();
for (int i = 0; i < ve.size(); ++i) {
if ( i + 2 < ve.size() && ve[i + 2] == "you" && ve[i + 1] == " " && (ve[i] == "could" || ve[i] == "can") ) {
g.push_back("I " + ve[i]);
i += 2;
} else g.push_back(ve[i]);
}
for (int i = 0; i < g.size(); ++i) {
if (g[i] == "I" || g[i] == "me") g[i] = "you";
}
string ans;
for (auto v:g) ans += v;
return ans;
};
for (int i = 0; i < n; ++i) {
string s;
getline(cin, s);
cout << s << '\n';
cout << "AI: ";
cout << check(s) << '\n';
}
}
signed main() {
// ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
}
7-8前世档案
goooogo
思路:将串看成二进制数即可
查看代码
void solve() {
int n, m;
cin >> n >> m;
for (int i = 0; i < m; ++i) {
string s;
cin >> s;
int ans = 0;
for (int j = 0; j < n; ++j) {
if (s[j] == 'y')ans *= 2;
else ans *= 2, ans ++;
}
cout << ans + 1 << '\n';
}
}
7-9抢红包
qwq
思路:用结构体存储信息并排序
查看代码
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;
struct E {
int s;
int cnt, id;
bool operator<(const E &e)const {
if (s != e.s) return s > e.s;
if (cnt != e.cnt) return cnt > e.cnt;
return id < e.id;
}
};
void solve() {
int n;
cin >> n;
vector<E> ve(n + 1);
for (int i = 1; i <= n; ++i) {
ve[i].id = i, ve[i].cnt = 0, ve[i].s = 0;
}
for (int i = 1, x; i <= n; ++i) {
cin >> x;
for (int j = 0; j < x; ++j) {
int id, s;
cin >> id >> s;
ve[id].s += s, ve[id].cnt ++;
ve[i].s -= s;
}
}
sort(ve.begin() + 1, ve.end());
for (int i = 1; i <= n; ++i) {
cout << ve[i].id << ' ';
cout << fixed << setprecision(2) << ve[i].s * 0.01 << '\n';
}
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
}
7-10红色警报
思路:注意到n并不大,可以考虑暴力点的解法,可以将一个点所在的集合包含的边里删去与该点相连的边后,看该集合是否还是一个集合,这里用并查集来维护
查看代码
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;
vector<int> vis;
vector<int> fa;
int find(int x) {
if(x != fa[x]) fa[x] = find(fa[x]);
return fa[x];
}
void mer(int a, int b) {
a = find(a), b = find(b);
if(a != b)fa[b] = a;
}
void solve() {
int n, m;
cin >> n >> m;
vis = fa = vector<int> (n);
vector<vector<int > > ve(n);
for (int i = 0; i < m; ++i) {
int u, v;
cin >> u >> v;
ve[u].push_back(v),ve[v].push_back(u);
}
int k;
cin >> k;
vector<int> st(n);
for (int i = 0, o; i < k; ++i) {
cin >> o;
st[o] = 1;
for (int j = 0; j < n; ++j) fa[j] = j, vis[j] = 0;
queue<int> q;
for (auto v:ve[o]) {
if (!st[v]) q.push(v);
}
while (q.size()) {
auto t = q.front();
q.pop();
if (vis[t])continue;
vis[t] = 1;
for (auto v:ve[t]) {
if (st[v] || vis[v])continue;
// if (o == 0)
mer(t, v);
q.push(v);
}
}
set<int> se;
for (int j = 0; j < n; ++j) {
if (vis[j]) {
int v = find (j);
// if (o == 1) cout << v << ' ';
se.insert(v);
}
}
if (se.size() <= 1) {
cout << "City " << o << " is lost.\n";
} else {
cout << "Red Alert: City " << o << " is lost!\n";
}
if (i == n - 1) {
cout << "Game Over.";
}
}
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
}
7-11排座位
qwq
思路:因为朋友的朋友是朋友,用并查集维护朋友集合,并且死对头关系不传递,直接矩阵记录即可,判断每种情况
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;
vector<int> fa;
int find(int x) {
if(x != fa[x]) fa[x] = find(fa[x]);
return fa[x];
}
void mer(int a, int b) {
a = find(a), b = find(b);
if(a != b)fa[b] = a;
}
void solve() {
int n, m, k;
cin >> n >> m >> k;
fa = vector<int> (n + 1);
vector no(n + 1,vector<int> (n + 1));
for (int i = 1; i <= n; ++i) fa[i] = i;
for (int i = 0; i < m; ++i) {
int u, v, p;
cin >> u >> v >> p;
if (p == 1) mer(u, v);
else no[v][u] = no[u][v] = 1;
}
for (int i = 0; i < k; ++i) {
int u, v;
cin >> u >> v;
int uu = find(u), vv = find(v);
if (uu == vv && !no[u][v]) cout << "No problem\n";
else if (uu == vv && no[u][v])cout << "OK but...\n";
else if (uu != vv && !no[u][v])cout << "OK\n";
else cout <<"No way\n";
}
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
}
7-12这是二叉搜索树吗?
思路:前序序列的特点就是,第一个点为根节点,剩下一部分为左子树,一部分为右子树,并且由于题目给的是二叉搜索树,左子树是小于根节点,右子树是大于等于根节点(镜像相反),那直接递归,判断为一棵二叉搜索树的同时,转换成后续序列
查看代码
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;
int n;
vector<int> ans, pre;
bool isl = true;
void get(int L, int R) {
if (L > R)return ;
int r = L + 1, l = R;
if (isl) {
while (r <= R && pre[r] < pre[L]) r ++;
while (l >= L + 1 && pre[l] >= pre[L]) l --;
} else {
while (r <= R && pre[r] >= pre[L]) r ++;
while (l >= L + 1 && pre[l] < pre[L]) l --;
}
if (r - l != 1) return ;
get(L + 1, l), get(r, R);
ans.push_back(pre[L]);
}
void solve() {
cin >> n;
pre = vector<int > (n);
for (int i = 0; i < n; ++i) {
cin >> pre[i];
}
get(0, n - 1);
if (ans.size() != n) {
ans.clear();
isl = false;
get(0, n - 1);
}
if(ans.size() != n) cout << "NO\n";
else {
cout << "YES\n";
for (int i = 0; i < n; ++i) {
cout << ans[i];
if (i < n - 1) cout << ' ';
}
cout << '\n';
}
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
}
7-13肿瘤诊断
思路:还还还是并查集,合并6个方向的1,由于我是边读入边合并,只需要合并3个方向即可
查看代码
#include<bits/stdc++.h>
using namespace std;
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;
const int dx[4] = {0,-1}, dy[4] = {-1, 0};
struct E {
int fa, cnt;
};
vector<E> ve;
int find(int x) {
if (x != ve[x].fa)
ve[x].fa = find(ve[x].fa), ve[ve[x].fa].cnt += ve[x].cnt, ve[x].cnt = 0;
return ve[x].fa;
}
void mer(int a, int b) {
a = find(a), b = find(b);
if (a != b){
ve[b].fa = a;
ve[a].cnt += ve[b].cnt, ve[b].cnt = 0;
}
}
void solve() {
int n, m, l, t;
cin >> m >> n >> l >> t;
ve = vector<E>(n * m * l + 5);
vector g(m, vector<int>(n) );
for (int i = 0; i < ve.size(); ++i) ve[i].fa = i, ve[i].cnt = 0;
for (int k = 0; k < l ; ++k) {
for (int i = 0; i < m; ++i) {
for (int j = 0; j < n; ++j) {
bool ok = false;
if (g[i][j]) ok = true;
cin >> g[i][j];
if (g[i][j] == 0)continue;
int id = k * n * m + i * n + j;
id = find(id);
ve[id].cnt += g[i][j];
if (j > 0 && g[i][j - 1]) {
int idd = k * n * m + i * n + j - 1;
mer(id, idd);
}
if (i > 0 && g[i - 1][j]) {
int idd = k * n * m + (i - 1) * n + j;
mer(id, idd);
}
if (ok) {
int idd = (k - 1) * n * m + i * n + j;
mer(id, idd);
}
}
}
}
set<int>se;
for (int i = 0; i < ve.size(); ++i) {
int v = find(i);
se.insert(v);
}
int ans = 0;
for (auto v:se) {
int u = find(v);
if (ve[u].cnt >= t)ans += ve[u].cnt;
}
cout << ans;
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
}
7-14迎风一刀斩
7-15特殊堆栈
思路:由于需要找中值,这里的值最大1e5,并且还有pop操作(删除),可以用数据结构维护每个值的个数,由区间和来二分中值
查看代码
#include<bits/stdc++.h>
using namespace std;
//#define int long long
#define PII pair<int, int>
#define PDI pair<double, int>
const double eps = 1e-12;
const int N = 1e5 + 5;
int c[N], n;
int lowbit(int x) {return x & -x;}
void add(int x, int k) {
while (x <= 1e5) {
c[x] += k;
x += lowbit(x);
}
}
int get(int x) {
int ans = 0;
while (x > 0) {
ans += c[x];
x -= lowbit(x);
}
return ans;
}
int getsum(int l, int r) {
return get(r) - get(l - 1);
}
void solve() {
cin >> n;
stack<int> st;
for (int i = 0; i < n; ++i) {
string s;
cin >> s;
if (s == "Push") {
int x;
cin >> x;
st.push(x);
add(x, 1);
} else if(s == "Pop") {
if (st.empty()) cout << "Invalid\n";
else {
int x = st.top();
add(x, -1);
cout << x << '\n', st.pop();
}
} else if (s == "PeekMedian") {
if (st.empty()) cout << "Invalid\n";
else {
int cnt = (st.size() + 1) / 2;
int l = 1, r = 1e5, x;
while (l <= r) {
int mid = ( l + r ) / 2;
if( getsum(1, mid) >= cnt ) x = mid, r = mid - 1;
else l = mid + 1;
}
cout << x << '\n';
}
}
}
}
signed main() {
ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
int T = 1;
// cin >> T;
while (T--) {
solve();
}
}