牛客周赛64

https://ac.nowcoder.com/acm/contest/92662#question)(比赛链接)

目录

A.小红的对错判断

B.小红的幂表达

C.小红的前缀询问

D.小红和小紫的博弈游戏

E.小红的字符串重排

F.小红的树上路径查询(easy)

G.小红的树上路径查询(hard)


A.小红的对错判断

1.思路

        判断字符串长度是否为3且s[0]是否为y或Y,s[1]是否为e或E,s[2]是否为s或S

2.代码

#include <bits/stdc++.h>
using namespace std;

signed main(){
    string s;
    cin>>s;
    if(s.length()==3&&(s[0]=='Y'||s[0]=='y')&&(s[1]=='E'||s[1]=='e')&&(s[2]=='S'||s[2]=='s')){
        cout<<"accept"<<endl;
    }else{
        cout<<"wrong answer"<<endl;
    }
    return 0;
}

B.小红的幂表达

1.思路

        利用for循环遍历所有的指数情况,从1到x,a^b=x,则a=pow(x,1.0/b),求出a,若a^b能等于x则输出对应的幂的表达式。需要注意的是,因为浮点数精度的问题,需要判断(a+1)^b是否等于x,以及(a-1)^b是否等于x。下面的结果就是浮点数精度问题导致的

    int t = pow(64,1.0/3);
    cout<<pow(64,1.0/3)<<endl;  // 4
    cout<<t<<endl;              // 3

        或利用for循环遍历所有底数情况,从x到2,若对于k=1,能通过乘法运算变为x则输出相应的幂的表达式

2.代码

#include <bits/stdc++.h>
using namespace std;

signed main(){
    int x;
    cin>>x;
    cout<<x<<endl;
    for(int i=1;i<=x;i++){
        int b = i;
        int a = pow(x,1.0/i);
        if(pow(a,i)==x){
            cout<<"="<<a<<"^"<<b<<endl;
        }else if(pow(a+1,i)==x){
            cout<<"="<<a+1<<"^"<<b<<endl;
        }else if(pow(a-1,i)==x){
            cout<<"="<<a-1<<"^"<<b<<endl;
        }
    }
    return 0;
}
#include <bits/stdc++.h>
#define int long long
using namespace std;

signed main(){
    int x;
    cin>>x;
    cout<<x<<endl;
    for(int i=x;i>=2;i--){
        int k=1;
        int b=0;
        while(k<x){
            k*=i;
            b++;
        }
        if(k==x){
            cout<<"="<<i<<"^"<<b<<endl;
        }
    }
    return 0;
}

C.小红的前缀询问

1.思路

        用map<int,int>来维护当前位置与新输入的数相同的个数,每次新输入一个数进行累计即可

2.代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

map<int,int>mp;

signed main(){
    int n;
    cin>>n;
    int sum=0;
    for(int i=1;i<=n;i++){
        int t;
        cin>>t;
        sum+=mp[t];
        mp[t]++;
        cout<<sum<<" \n"[i==n];
    }
    return 0;
}

D.小红和小紫的博弈游戏

1.思路

        令a[1]、a[4]为一组,a[2]、a[3]为一组,每次操作相当于从每组中抽取一个元素进行减1,直到其中一组的两个元素都为0的时候无法操作,因此两组的和较小的那组先两个元素到0,因此以两组和较小的那组为判断依据,根据奇偶性判断结果

        

2.代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

int a[5];

void solve(){
    for(int i=1;i<=4;i++){
        cin>>a[i];
    }
    int re = min(a[1]+a[4],a[2]+a[3]);
    if(re%2==0){
        cout<<"yukari"<<endl;
    }else{
        cout<<"kou"<<endl;
    }
}

signed main(){
    int t;
    cin>>t;
    while(t--){
        solve();
    }
    return 0;
}

E.小红的字符串重排

1.思路

        首先判断能否重排,若字符串中众数>字符串长度的一半,则不能重排,否则可以

        设原字符串为ababacc,可以的情况,利用vector<char,int>a保存每个字符在原字符串的位置,并按字符串大小进行排序,如:aaabbcc,现在考虑映射关系

        对于现在a中每个字符的位置,映射元素index=(i+max)%n(n为字符串长度),因为index=(i+max)%n能保证对应的映射元素绝对不同于自身

        比如现在的aaabbcc,第一个a映射元素为第一个b,第二个a映射元素为第二个b,第三个a映射元素为第一个c,第一个b映射元素为第二个c。所以根据映射元素,将每个字符置换到对应的映射元素的位置。如aaabbcc中第一个a的字符串中的位置为1,第一个b在字符串中的位置为2,可以选择将a放到2或者将b放置到1,两种方法选择其中一种进行置换即可

2.代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

signed main(){
    string s;
    cin>>s;
    int max1=0;
    for(char i='a';i<='z';i++){
        max1 = max<int>(max1,count(s.begin(),s.end(),i));
    }
    if(max1>s.length()/2){
        cout<<-1<<endl;
        return 0;
    }
    vector<pair<char,int>>a(s.length());    // 存放字符在s中的位置
    vector<char>ans(s.length());            // 存放结果
    for(int i=0;i<s.length();i++){
        a[i] = {s[i],i};
    }
    sort(a.begin(),a.end());
    for(int i=0;i<s.length();i++){
        int index = (i+max1)%s.length();
        ans[a[index].second] = a[i].first;
        // ans[a[i].second] = a[index].first;
    }
    for(int i=0;i<s.length();i++){
        cout<<ans[i];
    }
    return 0;
}

F.小红的树上路径查询(easy)

1.思路

        总共进行三次bfs,第一次以左端点为起点对所有点进行遍历,得到左端点到各个点的距离;第二次以右端点为起点对所有点进行遍历,得到右端点到各个点的距离。那么如何判断某个点是在左端点到右端点的这条简单路径上,则是某个节点到两个端点的距离之和为两个端点之间的距离即可。通过前两次bfs,即可得到处于简单路径上的所有节点,最后一次bfs,则以这些节点对剩余节点进行遍历获取距离加起来即可

2.代码

#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 1e5+7;

vector<int>a[N];
int visf[N],disf[N];    // 某个节点是否遍历过以及保存左端点到各个节点的距离
int viss[N],diss[N];    // 某个节点是否遍历过以及保存右端点到各个节点的距离
int vist[N],dist[N];    // 某个节点是否遍历过以及保存路径上的节点到非路径节点的距离
vector<int>b;   // 存储三次bfs遍历的起始节点
vector<int>bl;
vector<int>br;

void bfs(vector<int>b, int dis[], int vis[]){
    queue<int>q;
    for(auto t:b){
        q.push(t);
        vis[t] = 1;
        dis[t] = 0;
    }
    while(q.size()){
        int top = q.front();
        q.pop();
        for(int i=0;i<a[top].size();i++){
            int lb = a[top][i];
            if(vis[lb]){
                continue;
            }
            dis[lb] = dis[top] + 1;
            vis[lb] = 1;
            q.push(lb);
        }
    }
}

signed main(){
    int n,q;
    cin>>n>>q;
    for(int i=1;i<=n-1;i++){
        int u,v;
        cin>>u>>v;
        a[u].push_back(v);
        a[v].push_back(u);
    }
    int l,r;
    cin>>l>>r;
    bl.push_back(l);
    br.push_back(r);
    bfs(bl,disf,visf);
    bfs(br,diss,viss);
    int distancelr = disf[r];
    for(int i=1;i<=n;i++){
        // 若某个节点到两个端点的距离和为两个端点的距离则为简单路径上的节点
        if(disf[i]+diss[i]==distancelr){
            b.push_back(i);
        }
    }
    bfs(b,dist,vist);
    int ans = 0;
    for(int i=1;i<=n;i++){
        if(dist[i]!=0){
            ans+=dist[i];
        }
    }
    cout<<ans<<endl;
    return 0;
}

G.小红的树上路径查询(hard)

待补。。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值