天梯赛 训练round 3
Posted Yaqu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了天梯赛 训练round 3相关的知识,希望对你有一定的参考价值。
7-9 特立独行的幸福 (25 分)
题意:
一个数进行各个位上的数字求平方和 得到下一个数 一直这样操作 直到最后等于1 那么就称这个数为幸福数 但是要满足没有其他数经过它然后最终变成1 求一个范围内的独立幸福数
思路:
遍历这个范围内的数迭代 这个数 每次用vector储存由他迭代而来的数 且标记 这些数为非独立数 如果遇到循环就说明这个数不是独立幸福树跳出循环 当迭代结果是1时就停止循环然后标记这个数是独立的 再记录它的附和数的个数 即vector的大小 用map记录 最后只要再遍历一遍范围 将是独立幸福数的信息输出即可
因为数据并不大 只要模拟就好 想复杂了反而容易错
#include <bits/stdc++.h> #include <cstdlib> #include <cmath> #define ll long long using namespace std; const int N = 1e5 + 10; int n, m, cnt, a[1010], ndl[N], vis[N]; bool isprime(int x)//判断素数 if(x <= 1) return false; for(int i = 2; i * i <= x; i++) if(x % i == 0) return false; return true; vector<int>v; map<int, int> mp; int sp(int x)//各位数平方 int ans = 0; while(x > 0) ans += (x % 10) * (x % 10); x /= 10; return ans; int main() ios::sync_with_stdio(false); cin.tie(0); cin >> n >> m; for(int i = n; i <= m; i++) vector<int> v; int x = i; while(x != 1) int s = sp(x), ff = 1; x = s; for(int j = 0; j < v.size(); j++) if(s == v[j])//遇到循环 //ndl[s] = 1; //ndl[i] = 1; ff = 0; break; if(!ff) break; v.push_back(s); ndl[s] = 1; if(x == 1) mp[i] = v.size();//是幸福数 记录它的附和数个数 int flag = 0; for(int i = n; i <= m; i++) //一定要加上!mp[i]因为前面当遇到循环时 没有将s 和i标记为非独立幸福数 (而如果有前面的注释部分可以不用!mp[i]) if(ndl[i] || !mp[i]) continue; if(isprime(i)) cout << i << " " << mp[i] * 2 << "\\n"; else cout << i << " " << mp[i] << "\\n"; flag = 1; if(!flag) cout << "SAD\\n"; return 0;
7-10 冰岛人 (25 分)
题意:
一个人的名字有名 和 姓组成 如果是普京人 那么儿子的姓是父亲的名+sson 女儿的姓是父亲的名+sdottir 不是普京人 男人姓后面加m 女人姓后面加f
给n个人名 和 姓 再q次询问 给出两个人的名和姓 没有后缀 如果其中有一个不存在输出“NA" 如果为同性别 输出 ”Whatever“ 其余判断两人5代以内是否有同一个祖先(五代内没有共同祖先的要求是 两人的共同祖先比任何一方的曾祖父大)
思路:
这题主要要灵活运用map和 string 然后注意判断五代以内共同祖先的方法 具体看代码及注释
我这最后一个测试点超时了 之后再优化吧
#include <iostream> #include <map> #include <cstdio> #include <string> #include <vector> #include <queue> #include <algorithm> #define ll long long #define pi acos(-1) #define FF ios::sync_with_stdio(false), cin.tie(0) using namespace std; const int mod = 1e9 + 7; const int N = 1e6 + 10; const int inf = 0x3f3f3f3f; int n, k; string s; map<string, string>fa; map<string, int>sx; bool judge(string a, string b) //判断5代内是否有共同祖先 共同祖先可能不是同一辈的 int i = 1, j; for (string xx = a; sx[xx]; i++) j = 1; for (string yy = b; sx[yy]; j++) //循环结束的条件是后面已经没有人了sx可以标记该人是否存在 if (i > 4 && j > 4) //5代以外了直接跳出循环 标记真 return true; if (xx == yy && (i <= 4 || j <= 4)) //5代以内 公共祖先比至少一方的曾曾祖父小 return false; yy = fa[yy]; xx = fa[xx]; return true; //这个不对不符合祖先比任何一方的曾祖父大 而要求了比两方都大 /*bool judge(string a, string b) string xx = a, yy; for (int i = 1; i < 5; i++) yy = b; for (int j = 1; j < 5; j++) if (xx == yy) return false; if (yy.empty()) break; yy = fa[yy]; if (xx.empty()) break; xx = fa[xx]; return true; */ void solve() cin >> n; string x, y; for (int i = 1; i <= n; i++) cin >> x >> y;//可以直接这样输入 应为cin会跳过空白符 if (y.back() == \'n\') //s.back()获取s的最后一个字符 fa[x] = y.substr(0, y.size() - 4);//用substr()函数获取姓 sx[x] = 1;//记录性别 else if (y.back() == \'r\') fa[x] = y.substr(0, y.size() - 7); sx[x] = 2; else if (y.back() == \'m\') sx[x] = 1; else sx[x] = 2; int q; cin >> q; string a, s1, b, s2; for (int i = 1; i <= q; i++) cin >> a >> s1 >> b >> s2;//可以这样写 cin会跳过空白符 s1 s2主要就是储存输入对后面没影响 if (!sx[a] || !sx[b]) //有一方不存在 cout << "NA\\n"; else if (sx[a] == sx[b]) //同性别 cout << "Whatever\\n"; else //判断是否再5带内有共同祖先 if (judge(a, b)) cout << "Yes\\n"; else cout << "No\\n"; int main() FF; solve(); return 0;
7-12 彩虹瓶 (25 分)
题意:
几种颜色按顺序填 每次去搬来一种颜色 是当前要填的就填下 不是就暂时叠放到临时架子上 存放的物品不能超过架子的容量m 按先后顺序叠放 后续也按从上到下取 如果要取的物品上还有物品也无法顺利填好颜色 求是否能顺利填好颜色
思路:
利用栈简单模拟就好了 就是要注意多个测试例子 每次要把栈清空 stack 没有clear()
#include <bits/stdc++.h> #include <cstdlib> #define ll long long using namespace std; const int N = 1e5 + 10; int ans[500]; vector<int> g[N]; int n, m, k, a[1010]; queue<int>q; stack<int>st; int main() ios::sync_with_stdio(false); cin.tie(0); int n, yy; cin >> n >> m >> k; while(k --) while(!st.empty()) st.pop();//清空数据 for(int i = 1; i <= n; i++) cin >> a[i]; int pre = 1, flag = 1;//pre代表当前要填颜色的编号 for(int i = 1; i <= n; i++) if(a[i] != pre) //不符合先放到临时架子上 st.push(a[i]); if(st.size() > m)//临时架子满出了就不符合 flag = 0; break; else pre++;//可以填颜色 pre就指向下一个颜色 while(!st.empty())//再去看看临时架子上的颜色有没有可填的 int xx = st.top(); if(xx != pre) break; while(xx == pre) st.pop(); pre++; if(st.empty()) break; xx = st.top(); //如果栈不为空说明 不能顺利填颜色 if(flag && st.empty()) cout << "YES\\n"; else cout << "NO\\n"; return 0;
以上是关于天梯赛 训练round 3的主要内容,如果未能解决你的问题,请参考以下文章