牛客周赛 Round 76 : 题解

A : 小红出题     题目链接

思路: 只有 周1-周5 工作  ,所以先算有多少个星期,再乘5; 算不满一星期的天数 , 特殊判断如果是6天就按5天算。

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

int main()
{
	int n;
    cin>>n;
    
    int t=n/7;
    int ans=t*15;
    n-=t*7;
    if(n==6)
    {
        ans+=15;
    }
    else
    {
        ans+=n*3;
    }
    cout<<ans<<endl;
	return 0;
}

B : 串串香   题目链接

思路: 非空字串最多  , 最短的字串匹配的机会肯定更多啊, 所以直接统计单个字符出现的次数即可。(如果一个字符串s , 匹配最多字串是k(假设两个字符),如果k中有两个a (a又是k的字串了), 这样(a也是s字串) 不就 a的数量比k多了 所以找最小字串出现次数。

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

int main()
{
	int n;
    string s;
    cin>>n>>s;
    
    unordered_map<char,int> hash;
    
    for(int i=0;i<n;i++)
    {
        hash[s[i]]++;
    }
    
    string ans;
    int ans1=-1;
    bool flag=false;
    for(auto &[v,x]:hash)
    {
        if(!flag || ans1 < x)
        {
            flag=true;
            ans = v;
            ans1 = x;
        }
    }
    
    cout<<ans<<endl;
    
    
	return 0;
}

C :  小红的gcd   题目链接

思路 : gcd 最大公约数  :  两个数的公约数一定小于这两个数,会越来越小 , 其实求全部数的最大公约数 即为答案。

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

int main()
{
	int n;
    cin>>n;
    vector<int> nums(n);
    
    for(int i=0;i<n;i++)
    {
        cin>>nums[i];
    }
    
    long long t=nums[0];
    
    for(int i=1;i<n;i++)
    {
        t = gcd(t,nums[i]);
    }
    
    
    cout<<t*n<<endl;
	return 0;
}

D : 奇偶调整    :   这题假了,仅供参考!题目链接

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

int n,m,k;

int main()
{
    //偶数/2 m     奇数-1  k
	scanf("%d%d%d",&n,&m,&k);
    long long sum=0;
    priority_queue<int> h;  //大到小
    
    for(int i=0;i<n;i++)
    {
        int z;
        cin>>z;
        h.push(z);
    }
    
    while(m || k)
    {
        bool flag=false;
        int t=h.top();
        h.pop();
        if(t==0)break;
        if(t%2 && k)
        {
            k--;
            t^=1;
            flag=true;
        }
        else if(t%2==0 && m)
        {
            m--;
            t/=2;
            flag=true;
        }
        if(!flag)
        {
            sum+=t;
        }
        else h.push(t);
    }
    
    while(h.size())
    {
        sum+=h.top();
        h.pop();
    }
    
    cout<<sum<<endl;
	return 0;
}

E :  幂次进近    题目链接

思路:数学,求n的1/k次方               也可以二分+快速幂  (注意__int128 , 要注意确定上限)

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


int main(){
    long double n,k,t;
    ll ans;
    cin>>t;
    while(t--)
    {
        cin>>n>>k;
        ans=pow(n,(1/k));
        if(n-pow(ans,k) < pow(ans+1,k)-n) cout<<ans<<endl;
        else cout<<ans+1<<endl;
    }
    return 0;
}

F : 同位序列   : 题目链接

思路:求每个ai 的g(ai)  并记录  , dp找最大个数 (倒退,从大数开始) 

求g(x) =  从低位开始找出现连续的1,  

参考官解视频(官解用了next_permutation()): 

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

void solve()
{
	int n;
	cin>>n;
	map<int,int> g;
	vector<int> a(n);
	for(int i=0;i<n;i++)
	{
		cin>>a[i];
	}
    //g(x)
	for(int i=0;i<n;i++)
	{
        int z=a[i];
        int count=0;
        int pos=0;
        bool flag=false;
        for(int i=0;i<32;i++)
        {
            if(!flag)
            {
                if(z & (1<<i))
                {
                    flag=true;
                    count++;
                    z ^= (1<<i);
                }
                else
                {
                    continue;
                }
            }
            else
            {
                if(z & (1<<i))
                {
                    count++;
                    z ^= (1<<i);  //变0
                }
                else
                {
                    pos=i;
                    break;
                }
            }
        }
        z |= (1<<pos);
//         cout<<z<<endl;
        for(int i=0;i<count-1;i++)
        {
            z |= (1<<i);
        }
        
//         cout<<z<<endl;
        
        g[a[i]] = z;
	}

    
	set<int> ans;
	sort(a.rbegin(),a.rend());   //大到小  倒推
	map<int,int> mp;
	int ma=0,id=0;
	
	for(auto x : a)
	{
		if(mp.contains(g[x])) mp[x] = mp[g[x]] + 1;
		else mp[x] = 1;
		if(mp[x] > ma) ma = mp[x],id=x;
	}
	
	ans.insert(id);
	while(mp.contains(g[id]))
	{
		id = g[id];
		ans.insert(id);
	}	
	
	cout<<ans.size()<<endl;
	for(auto& x : ans)cout<<x<<" ";
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
	solve();
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值