2024牛客寒假算法基础集训营6(小白)

A:

这道题因为数据比较小,可以打表,

打出100以内素数表,然后暴力枚举判定。

手算也行,100以内答案只有30,42,66,70,78

写法一(手动计算):

#include <bits/stdc++.h>
using namespace std;
signed main() {
    cin.tie(0);
    cout.tie(0);
    int l, r;
    cin >> l >> r;
    for (int i = l; i <= r; i++) {
        if (i == 30 || i == 42 || i == 66 || i == 78 || i == 70) {
            cout << i << '\n';
            return 0;
        }
    }
    cout << -1 << '\n';
    return 0;
}

写法二(自动计算):

#include <bits/stdc++.h>
#define int long long
using namespace std;
vector<int> p;
void isprime()
{
	for (int i = 2; i <= 100; ++i)
	{
		int fa = 0;
		for (int j = 2; j * j <= i; ++j)
		{
			if (i % j == 0)
			{
				fa = 1;
				break;
			}
		}
		if(fa==0) p.push_back(i);//挑选100以内的素数
	}
}
signed main()
{
	ios::sync_with_stdio(0);
	cin.tie(0);
	int l, r;
	cin >> l >> r;
	isprime();
	for (int i = l; i <= r; ++i)
	{
		int sum = 0;
		int m = i;
		for (int j = 0; j < p.size(); ++j)
		{
			if (m % p[j] == 0) m = m / p[j], sum++;
		}
		if (m == 1&&sum==3)//判断三次方的答案
		{
			cout << i << '\n';
			return 0;
		}
	}
	cout << -1 << '\n';
	return 0;
}

B:

思路:寻找a[i]跟b[j]的差值绝对值最小,然后swap(a[ i ],a[ j ]),输出数组a[ ],原先用暴力的做法两层for循环,意料之中的超时了;改良后用lower_bound,将a按升序排列;寻找大于等于某值(>= x)的数,设为x2,mn1=abs(x2-x);寻找小于等于某值(<=x),设为x1,mn2=abs(x1-x),最后对比mn1,mn2的最小值为mn,记录其下标i,j值,直到有比mn更小的数是,时更新其下标;

lower_bound() 用于二分查找区间内第一个 大于等于某值(>= x) 的迭代器位置
upper_bound() 用于二分查找区间内第一个 大于某值(> x) 的迭代器位置

使用暴力的错误代码;

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N];
int b[N];
int tag1,tag2;
int mi=0x3f3f3f3f;
signed main()
{
    cin.tie(0);
    cout.tie(0);
     int n;
    cin>>n;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    for(int j=1;j<=n;j++)
    cin>>b[j];
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=n;j++)
        {
            if(abs(a[i]-b[j])<mi)
            {
                mi=abs(a[i]-b[j]);
                tag1=i;
                tag2=j;
            }
        }
    }
    swap(a[tag1],a[tag2]);
    for(int i=1;i<=n;i++) cout<<a[i]<<" ";
}

使用lower_bound的正确代码:

#include <bits/stdc++.h>
using namespace std;
int a[100010],b[100010];
void solve()
{
    int n,t1,t2,ans=0x3f3f3f3f;
    cin >> n;
    for(int i=1;i<=n;i++) cin >> a[i];
    for(int i=1;i<=n;i++) cin >> b[i];
    sort(a+1,a+1+n);
    //a[0]=INT_MAX;
    for(int i=1;i<=n;i++)
    {
        int x=lower_bound(a+1,a+1+n,b[i])-a;
        if(abs(a[x]-b[i])<ans)
        {
            t1=x;
            t2=i;
            ans=abs(a[x]-b[i]);
        }
        if(abs(a[x-1]-b[i])<ans)
        {
            t1=x-1;
            t2=i;
            ans=abs(a[x-1]-b[i]);
        }
    }
    swap(a[t1],a[t2]);
    for(int i=1;i<=n;i++)
        cout << a[i] << " ";
    return;
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    solve();
    return 0;
}

C:

思路:既然上面学了upper_bound,那就用其方法解决吧,预处理N以内斐波那契数列,找到<=x的数,设为x1,for循环3次,用a[ i ]记录答案,n=n-x1 , 循环结束后 当n==0时输出a[i];

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
 
ll f[50] = {0, 0, 1}, a[5];//f[0]=0,f[1]=0,f[2]=1;
 
int main() {
    int t, n;
    for (int i = 3; i <= 50; i++)
        f[i] = f[i - 1] + f[i - 2];
    cin >> t;
    while (t--) {
        cin >> n;
        for (int i = 1; i <= 3; i++) {
            int x = upper_bound(f + 1, f + 51, n) - f-1;
            a[i] = f[x], n -= f[x];
        }
        if (n)
            cout << -1;
        else
            cout << a[1] << ' ' << a[2] << ' ' << a[3];
        cout << endl;
    }
    return 0;
}

I:

怎么说呢,其实理解得还是有点笼统,列出二维矩阵后可以发现子矩阵的最大值为,a1(b1+b2+b3)+a2(b1+b2+b3)+a3(b1+b2+b3)----->(a1+a2+a3)*(b1+b2+b3),就相当于

( 正数 ) a的最大子串和*b的最大子串和或(负数)a的最小子串和*b的最小子串和(按道理是这样的)但是这样子只过了80% 。

#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N=1e5+10;
int a[N],b[N];
int s[N];
int dp1[N],dp2[N],dp3[N],dp4[N];
signed main()
{
   int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>a[i];
    }
    for(int i=1;i<=m;i++)
    {
        cin>>b[i];
    }
    int mmin1=1e14,mmax1=-1e14;
     int mmin2=1e14,mmax2=-1e14;
    for(int i=1;i<=n;i++)
    {
        dp1[i]=max(dp1[i-1]+a[i],a[i]);
        dp2[i]=min(dp2[i-1]+a[i],a[i]);
        mmax1=max(mmax1,dp1[i]);
        mmin1=min(mmin1,dp2[i]);
    }
    
    for(int i=1;i<=m;i++)
    {
        dp3[i]=max(dp3[i-1]+b[i],b[i]);
        dp4[i]=min(dp4[i-1]+b[i],b[i]);
        mmax2=max(mmax2,dp3[i]);
        mmin2=min(mmin2,dp4[i]);
    }
   
    int ans=max({mmax1*mmax2,mmax1*mmin2,mmin1*mmax2,mmin1*mmin2});
    cout<<ans;
}

找个机会做J题:

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define int long long
#define no cout << "NO" << endl
#define yes cout << "YES" << endl
#define endl "\n"
#define FAST                                                                   \
  ios::sync_with_stdio(false);                                                 \
  cin.tie(0);                                                                  \
  cout.tie(0);
 
const int N = 2e5 + 5;
 
vector<int> a[100010];
int ans[100010],f[100010];
string s;
int m=0;
void dfs(int u)
{
    f[u]=1;
    for(auto e:a[u])
    {
        dfs(e);
        f[u]+=f[e];
    }
    if(s[u]=='R')
    {
        if(f[u]%3==1&&f[u]!=1)
        {
            ans[u]=2;
            ans[a[u][0]]=2;
        }
        else if(f[u]%3==2)
            ans[u]=2;
        else if(f[u]==1)
        {
            m=1;
            return;
        }
        f[u]=0;
    }
}
void solve()
{
    int n;
    cin >> n;
    cin >> s;
    s=' '+s;
    ans[1]=1;
    for(int i=2;i<=n;i++)
    {
        int x;
        cin >> x;
        a[x].push_back(i);
        ans[i]=1;
    }
    dfs(1);
    if(m) cout << -1;
    else
    {
        for(int i=1;i<=n;i++)
            cout << ans[i];
    }
}
signed main() {
   solve();
}

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值