牛客周赛 Round 30

前面几道签到题用最近学的java写的,学得不多只能用java写前两题🤣

目录

A.小红得删字符

B.小红的正整数

C.小红构造回文

D.小红的整数操作

E.小红的树上染色 


A.小红得删字符

思路: 签到题

code

import java.util.Scanner;

public class Main{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        String s=sc.next();
        for(int i=0;i<s.length();i++)
        {
            if(i!=1)
            System.out.print(s.charAt(i));
        }
       // System.out.print(s);
    }
}

B.小红的正整数

 思路:签到题,先将字符串排序,如果有0的话就用第一个非零数与第一个零交换位置

code

import java.util.Scanner;
import java.util.Arrays;

public class Main{
    public static void main(String[] args){
        Scanner sc=new Scanner(System.in);
       // int x; x=sc.nextInt();
       
        String s=sc.next();
        int k=s.length();
        char[] c=new char[k];
        for(int i=0;i<k;i++)
        c[i]=s.charAt(i);
        Arrays.sort(c);
        int pos=0;
        if(c[0]=='0')
        {
            for(int i=0;i<k;i++)
                if(c[i]!='0')
                {
                    pos=i;
                    break;
                }
           char t=c[0];
            c[0]=c[pos];
            c[pos]=t;
            for(int i=0;i<k;i++)
                System.out.print(c[i]);
        }
        else
          for(int i=0;i<k;i++)
                System.out.print(c[i]);
    }
}

C.小红构造回文

思路:回文串根据长度分为两种情况,我们每次只需要去遍历回文的一半的长度,然后交换两个不同的字符,另一半也对应的交换两个不同的字符就可以得到一个新的回文字符串了

(1) 长度为偶数 ,例如 aaaa 它的前一半只出现了一种字符,所以无解,而aabbaa前一半出现了两种字符,位置在 a0  a2,另一半对应的位置分别为a0+(len/2-a0-1)*2+1,a2+(len/2-a2-1)*2+1.

  (2)   长度为奇数 , 例如 aba 它的前一半只出现了一种字符,所以无解,而 aabcbaa 前一半出现了两种字符,位置在a0 a2 ,另一半对应的位置分别为a0+(len/2-a0)*2, a1+(len/2-a1)*2.

code:

#include <iostream>
#include <cstring>
#include <map>
#include <algorithm>

using namespace std;

const int N = 1e5+5;
pair<char,int> q[N];

int main()
{
    string s;cin>>s;
    map<char,int> mp;
    int len=s.size()/2,k=s.size();
    int cnt=0;
    for(int i=0;i<len;i++)
    {
        if(!mp[s[i]]&&cnt<2)
        {
            q[cnt++]={s[i],i};
            mp[s[i]]++;
        }
    }
    if(mp.size()==1) puts("-1");
    else
    {
        int a=q[0].second,b=q[1].second;
        int a1,b1;
        if(k%2==0)
        a1=a+(len-a-1)*2+1,b1=b+(len-b-1)*2+1;
       
        else a1=a+(len-a)*2,b1=b+(len-b)*2;
       // cout<<a<<' '<<b<<endl<<a1<<' '<<b1<<endl;
        swap(s[a],s[b]);
        swap(s[a1],s[b1]);
        cout<<s;
    }
        
}

D.小红的整数操作

思路:数论中的一个定理 ——一个数a在区间[1,x]中的倍数个数为x/a个 ,我们可以先将 x,y 除以最大公约数,使它们变为最小质数,然后求l到r的最大下界和最小上界。

code:

#include <iostream>
#include <map>
#include <algorithm>
#include <cstring>
//#define int long long

using namespace std;

int32_t main()
{
    int x,y,l,r;cin>>x>>y>>l>>r;
    int t=__gcd(x,y);
    x/=t;
    y/=t;
    if(x>y) swap(x,y);
    int mind=(l+x-1)/x;
    int maxd=r/y;
    cout<<max(maxd-mind+1,0);
}

E.小红的树上染色 

思路:经典的树形dp,因为只有两种状态所有我们可以设置数组f[i][2],其中f[i][0]表示第i个节点未染色的染色方案,f[i][1]表示第i个节点染色的染色方案,如果第i个节点未染色,那么子节点一定要染色,因为是状态叠加,基于乘法原理状态转移方程为f[i][0]=f[i][0]*f[son][1],若第i个节点染色,那么子节点可以染或者不染,所以状态转移方程为f[i][1]=f[i][1]*(f[son][0]+f[son][1])

code:

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#define int long long
using namespace std;

constexpr int N = 1e5+5,mod=1e9+7;

vector<int> g[N];
int f[N][2];
int n;

void dfs(int u)
{
    f[u][0]=1,f[u][1]=1;
    for(auto t:g[u])
    {
        dfs(t);
        f[u][0]=(f[u][0]*f[t][1])%mod;
        f[u][1]=(f[u][1]*(f[t][1]+f[t][0]))%mod;
    }
}
int32_t main()
{
    cin>>n;
    for(int i=1;i<n;i++)
    {
        int a,b;cin>>a>>b;
        g[a].push_back(b);
    }
    dfs(1);
    cout<<(f[1][0]+f[1][1])%mod;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

SuperRandi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值