天梯赛 训练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的主要内容,如果未能解决你的问题,请参考以下文章

天梯赛和蓝桥杯省赛训练

天梯赛选拔2020.3.3

天梯训练赛

2019天梯赛第三次训练赛

2019天梯赛训练1

PTA-天梯赛训练六度空间(广搜)