2024牛客寒假算法基础集训营1

A DFS搜索

考点:双指针
思路:从左往右和目标字串依次比较,用bool来标记即可

#include <bits/stdc++.h>
using namespace std;
string s;
string s1 = "dfs";
string s2 = "DFS";
int n;
int main()
{
	cin >> n >> s;
    int i = 0,j = 0,k = 0; 
    bool fDFS = false,fdfs = false;
	//dfs 
    while(i < s.size() && j < s1.size())
    {
        if(s[i] == s1[j])
        {
            j++;
        }
        i++;
    }
    if(j == s1.size()) fdfs = true;
	//DFS
    i = 0;
    while(i < s.size() && k < s2.size())
    {
        if(s[i] == s2[k])
        {
            k++;
        }
        i++;
    }
    if(k == s2.size()) fDFS = true; 
    cout << fDFS << ' ' << fdfs << '\n';
    return 0;
}

B 关鸡

C 按闹分配

考点:排序,二分,前缀和
思路:0.o

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
const int N = 1e5 + 10;
i64 a[N],s[N];
i64 n,Q,tc;
// 二分
i64 check(i64 M) 
{
    i64 l = 0,r = n,mid,res = -1;
    while (l <= r) 
	{
        mid = (l + r) / 2;
        i64 dec = tc * (n - mid); // 计算不满意度增加量
        i64 t = s[mid] + tc; // 鸡完成办事的时刻
        if (dec <= M) 
		{ // 检查是否在容忍度范围内
            res = t;
            r = mid - 1;
        } 
		else 
            l = mid + 1;
    }
    return res;
}

int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cin >> n >> Q >> tc;
    for (i64 i = 1;i <= n;i ++) cin >> a[i];
    sort(a + 1,a + n + 1);
    for (i64 i = 1;i <= n;i ++) s[i] = s[i-1] + a[i];
    while (Q--)
    {
        i64 M; cin >> M;
        cout << check(M) << '\n';
    }
    return 0;
}


E 本题又主要考察了贪心

考点:dfs
思路:数据较小,情况多,没有明确的贪心,很容易想到dfs,让一号选手的对局必胜,然后去用dfs走其他所有的可能。

#include <bits/stdc++.h>
#define PII pair<int, int>
using namespace std;
using i64 = long long;
int n,m;
vector<int> a; 
vector<PII> mp; 
int res; 
// 更新排名 
int Rank() 
{
    int rank = 1;
    for (int i = 0;i < n;i ++) 
    {
        if (a[i] > a[0]) rank ++;
    }
    return rank;
}
// 用dfs枚举所有情况 
void dfs(int dep) 
{
	//出口 
    if (dep == m) 
	{ 
        res = min(res,Rank());
        return;
    }
    // 模拟胜、负、平
    int u = mp[dep].first - 1;
    int v = mp[dep].second - 1;
    // u 胜
    a[u] += 3;
    dfs(dep + 1);
    a[u] -= 3; 
    // v 胜
    a[v] += 3;
    dfs(dep + 1);
    a[v] -= 3; 
    // 平局
    a[u] += 1;
    a[v] += 1;
    dfs(dep + 1);
    a[u] -= 1; 
    a[v] -= 1; 
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);
    int t;cin >> t;
    while (t--)
    {
        cin >> n >> m;
        a.resize(n);
        for (int i = 0;i < n;i ++)
            cin >> a[i];
        mp.resize(m);
        for (int i = 0;i < m;i ++)
            cin >> mp[i].first >> mp[i].second;
        res = 0x3f3f3f3f; 
        dfs(0); 
        cout << res << '\n';
    }
    return 0;
}

G why买外卖

考点:思维,STL,排序
思路:把满减优惠从小到大排序,依次满足,只要能够买就继续往上优惠,维护更新最大值

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
vector<pair<int,int>> yh;
int n,m;
void solve()
{
    cin >> n >> m;
    i64 res = m;
    yh.resize(n);
    for(i64 i = 0;i < n;i ++) 
    {
        i64 a,b;
        cin >> a >> b;
        yh[i] = {a,b};
    }
    sort(yh.begin(),yh.end());
    i64 sum = 0;
    for(const auto& ab : yh)
    {
        sum += ab.second;
        if(sum + m >= ab.first)
        {
            res = max(sum + m,res);
        }
    }
    cout << res << '\n';
}
int main()
{
    int t;cin >> t;
    while(t --)
    {
        solve();   
    }
    return 0;
}

I It's bertrand paradox. Again!

考点:数学,思维
思路:bit-noob的方法:会保持圆心不变,一直改变半径,按道理来说圆的位置会更靠近中心,因为边界会收到半径限制,但是如果按照生成逻辑,生成的原因一定是因为边界问题,所以它新生成的圆,应该更靠近边界
buaa-noob的方法:会让圆更倾向于均匀分布,圆心会更随机
思路:出于这种原因,我们可以假设圆就在中间,来统计圆心绝对值的和,如果和大于一个阈值,说明是bit-noob的方法,相反就是buaa-noob

#include <bits/stdc++.h>
using namespace std;
using i64 = long long;
int main()
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    i64 s = 0;
    i64 n;cin >> n;
    for(int i = 0;i < n;i ++)
    {
        i64 x,y,r;
        cin >> x >> y >> r;
        s += abs(x) + abs(y);
    }
    //0-200,每次圆心绝对值之和的范围,假设圆心在+-50
    //那绝对值范围就是0-100,取集中,往上找阈值,为了更快速,我们可以倒着取值
    if(s > 88 * n)//范围取[74,99]都可以(别问为什么,问就是挨个试了一遍)
        puts("bit-noob");
    else 
        puts("buaa-noob");
    return 0;
}

L 要有光

考点:数学,思维
思路:要让地面阴影最大,考虑光源在杆上面只要不在地上都会出现夹角投影,肯定不是最大的,所以光源一定在地上,最大面积即为梯形面积,用相似比例可以得出结果

#include <bits/stdc++.h>
using namespace std;
int c,d,h,w;
void solve()
{
    cin >> c >> d >> h >> w;
    printf("%.10f\n",3.0*c*w);
}
int main()
{
    int t;cin >> t;
    while(t --)
    {
        solve();
    }
    return 0;
}

M 牛客老粉才知道的秘密

考点:思维
思路:很容易想到整除6一定结果为n/6,剩余的由于过去回来的对称性,一定会有两倍的int(n/6),向下取整是因为回去的时候一定和初始位置重合,会多一种,可以用数学归纳(找规律)得出

#include <bits/stdc++.h>
using namespace std;
int n;
void solve()
{
    cin >> n;
    if(n % 6 == 0) cout << n / 6 << '\n';
    else cout << n / 6 * 2 << '\n';
}
int main()
{
    int t;cin >> t;
    while(t --)
    {
        solve();
    }
    return 0;
}
全部评论

相关推荐

1 1 评论
分享
牛客网
牛客企业服务