2024牛客寒假算法基础集训营1 题解 ( A,M,L,G,C,E )

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

A DFS搜索

题意

找所给字符串中是否有依次出现的 'D' 'F' 'S''d' 'f' 's'

思路

所以可以依次判断两种情况

  1. 找到D再找F再找S
  2. 找到d再找f再找s

依次根据是否满足条件输出1或0

代码

/*******************************
| Author:  AlwaysBeShine
| Problem: DFS搜索
| Contest: NowCoder
| URL:     https://ac.nowcoder.com/acm/contest/67741/A
| When:    2024-02-02 13:00:53
| 
| Memory:  524288 MB
| Time:    2000 ms
*******************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

void solve(){

    int n;
    cin >> n;
    string s;
    cin >> s;

   	int cnt1 = 0,cnt2 = 0;

   	for(int i = 0;i < n;i++){

   		if(s[i] == 'D' && cnt1 == 0){

   			cnt1 = 1;

   		}else if(s[i] == 'F' && cnt1 == 1){

   			cnt1 = 2;

   		}else if(s[i] == 'S' && cnt1 == 2){

   			cnt1 = 3;

   		}

   		if(s[i] == 'd' && cnt2 == 0){

   			cnt2 = 1;

   		}else if(s[i] == 'f' && cnt2 == 1){

   			cnt2 = 2;

   		}else if(s[i] == 's' && cnt2 == 2){

   			cnt2 = 3;

   		}

   	}

   	if(cnt1 == 3){

   		cout << 1 << " ";

   	}else{

   		cout << 0 << " ";

   	}

   	if(cnt2 == 3){

   		cout << 1 << endl;

   	}else{

   		cout << 0 << endl;

   	}

}

int main(){

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int T;
    cin >> T;
    while(T--){

       solve();

    }

    return 0;
}

M 牛客老粉才知道的秘密

题意

屏幕固定一次性显示6题(例如1 2 3 4 5 6),共有 n 道题,若当前所显示的6道题的题号依次为 \(a,b,c,d,e,f\), 则向每次向左翻页时,新页面最左侧显示的题号为 \(min(1,a-6)\),同理每次向右翻页时,新页面最右侧显示的题号为\(min(n,f+6)\)

页面的最左侧可能出现多少不同的题号

思路

模拟一下会发现

如果题目数量 \(n\) ,能被 \(6\) 整除,
假设共 \(12\) 页,只能向右翻页 \(2\) 次,依次为 \(1,2,3,4,5,6\)\(7,8,9,10,11,12\)
再向左翻回去,依次为 \(7,8,9,10,11,12\)\(1,2,3,4,5,6\),只有两种可能
答案也就是 \(\frac{n}{6}\)

如果题目数量 \(n\) ,不能被6整除,只有最后翻到底的时候,会出现翻页后得到的新页面存在和上一页重复的题号的情况
假设共 13 页,可以向右翻页 \(3\) 次,依次为\(1,2,3,4,5,6\)\(7,8,9,10,11,12\) 还有 \(8,9,10,11,12,13\),往回翻的过程中,每次翻页后所得新页面的最左侧的题目和翻过来的过程中不再重叠,依次为 \(8,9,10,11,12,13\)\(2,3,4,5,6,7\) 还有 \(1,2,3,4,5,6\)
其他 \(n \bmod 6 \not= 0\), 同理,答案为 2 * \(\lfloor \frac{n}{6} \rfloor\)

代码

/*******************************
| Author:  AlwaysBeShine
| Problem: 牛客老粉才知道的秘密
| Contest: NowCoder
| URL:     https://ac.nowcoder.com/acm/contest/67741/M
| When:    2024-02-02 13:42:46
| 
| Memory:  524288 MB
| Time:    2000 ms
*******************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

void solve(){

    ll n;
    cin >> n;
    ll ans = 0;

    ans += n / 6;
    if(n % 6 != 0)ans += n / 6;
    cout << ans << endl;
}

int main(){

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int T;
    cin >> T;
    while(T--){

       solve();

    }

    return 0;
}

L 要有光

题意

如果绿幕高度不为 \(0\)

当点光源无限高时,所有区域都可以被照亮,逐渐降低点光源高度的过程中,逐渐出现未被点亮的区域,当点光源高度趋近于0时,未被点亮的面积趋于最大

当绿幕高度为 \(0\) 时,无遮挡,不会出现未被点亮的区域,即最大为 \(0\)

思路

屏幕截图 2024-02-22 225143.png

如果绿幕的高度不为 \(0\) ,求梯形面积即可。

代码

/*******************************
| Author:  AlwaysBeShine
| Problem: 要有光
| Contest: NowCoder
| URL:     https://ac.nowcoder.com/acm/contest/67741/L
| When:    2024-02-02 16:04:57
| 
| Memory:  524288 MB
| Time:    2000 ms
*******************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

void solve(){

    double c,d,h,w;
    cin >> c >> d >> h >> w;
    if(h <= 0){

    	cout << fixed << setprecision(8) << 0.00000000 << endl;

    }else{

    	double ans = 3*w *c;
    	cout << fixed << setprecision(8) << ans << endl;

    }

}

int main(){

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int T;
    cin >> T;
    while(T--){

       solve();

    }

    return 0;
}

G why买外卖

题意

\(n\) 张可叠加的 满 \(x\)\(y\) 元的优惠券, 本身手里有 \(m\) 元,问最多买多少钱的东西

思路

设第 \(i,j\) 张优惠券分别为 满 \(x_i\)\(y_i\) 元 和 满 \(x_j\)\(y_j\)
如果 \(x_i \le x_j\) ,如果最后能用上满 \(x_j\)\(y_j\) 元的优惠券,则 满 \(x_i\)\(y_i\) 元 的优惠券也可以被叠加使用,即变为 满 \(x_j\)\(y_j + y_i\) 元。

如何实现叠加过程?
当出现以上情况时,则将低满减额的折扣额加给高满减额的折扣额

叠加完毕后,判断

如何判断是否可以使用呢?
当 原价 \(\le\) 满减额 时,原价 - 优惠券折扣额 \(\le\) m 即可使用
即求 当 满减额 - 折扣额 \(\le\) m 时的 m - 折扣额 的最大值。

代码

/*******************************
| Author:  AlwaysBeShine
| Problem: why买外卖
| Contest: NowCoder
| URL:     https://ac.nowcoder.com/acm/contest/67741/G
| When:    2024-02-02 14:53:04
| 
| Memory:  524288 MB
| Time:    2000 ms
*******************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

void solve(){

    ll n,m;
    cin >> n >> m;
    vector<pair<ll,ll>> q;
    map<ll,int>pos;
    for(int i = 0;i < n;i++){

    	ll a,b;
    	cin >> a >> b;

    	if(pos[a] == 0){

    		q.push_back({a,b});
    		pos[a] = q.size() - 1;
    	}else{

    		q[pos[a]].second += b;

    	}

    }

    sort(q.begin(),q.end());

    for(int i = 0;i < q.size()-1;i++){

    	q[i+1].second += q[i].second;

    }

    ll res = -1;
    for(int i = q.size()-1;i >= 0;i--){
    	if(q[i].first - q[i].second <= m)
    	res = max(q[i].first+m-(q[i].first-q[i].second),res);

    }
    if(res == -1){

    	cout << m << endl;

    }else{

    	cout << res << endl;
    	
    }

}

int main(){

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int T;
    cin >> T;
    while(T--){

       solve();

    }

    return 0;
}

C 按闹分配

题意

有一长度为 \(n\) 的数组 t,第 \(i\) 个元素对应的不满意度 \(D_i = \sum_{i=1}^nt_i\)
定义 \(S = \sum_{i=1}^nD_i\),将一元素 \(x\) 插入数组 t 的第 \(i\) 位,新的数组有 \(S' = \sum_{i=1}^{n+1}D_i\)
求满足 \(S' - S \le M\)\(i\) 的最小值。

思路

\(S' - S = (n-i)*x + D_{i-1}\) ,求 \(i\) 的最小值。

代码

/*******************************
| Author:  AlwaysBeShine
| Problem: 按闹分配
| Contest: NowCoder
| URL:     https://ac.nowcoder.com/acm/contest/67741/C
| When:    2024-02-02 16:59:05
| 
| Memory:  524288 MB
| Time:    2000 ms
*******************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
			
int main(){
			
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
			
	ll n,Q,T,ans;
	cin >> n >> Q >> T;
	vector<ll>t(n+1,0);
	for(int i = 1;i <= n;i++){

		cin >> t[i];
		
	}

	sort(t.begin(),t.end());
	ll sum_min = 0;
	for(int i = 1;i <= n;i++){

		t[i] += t[i-1];
		sum_min += t[i];
	}

	while(Q--){
		ll M;
		cin >> M;
		
		ll cnt = M / T;

		if(M >= n*T){

                cout << T << endl;

		}else{

			cout << t[n-cnt] + T << endl;

		}
   		
	}


			
	return 0;
}

E 本题又主要考察了贪心

题意

\(n\) 个选手,第 \(i\) 名选手,目前得分为 \(a_i\),接下来有 \(m\) 场比赛,胜者得 3 分,平局均得 1 分。

求在最好情况下,第 \(1\) 名选手的排名最高为多少。

思路

看数据范围,搜索所有可能性即可

代码

/*******************************
| Author:  AlwaysBeShine
| Problem: 本题又主要考察了贪心
| Contest: NowCoder
| URL:     https://ac.nowcoder.com/acm/contest/67741/E
| When:    2024-02-05 23:26:34
| 
| Memory:  524288 MB
| Time:    2000 ms
*******************************/
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
// 0 输 1赢 2 平
int n,m,a[11],u[11],v[11];
int bt = 100;
void dfs(int round,int A[],int U[],int V[]){

	

	if(round == m+1){

		int cnt = 1;

		for(int i = 2;i <= n;i++){

			if(A[i] > A[1])cnt++;

		}

		bt = min(bt,cnt);
		return;
	}else{

		A[U[round]] += 3;
		dfs(round+1,A,U,V);
		A[U[round]] -= 3;

		A[V[round]] += 3;
		dfs(round+1,A,U,V);
		A[V[round]] -= 3;

		A[V[round]]++;
		A[U[round]]++;
		dfs(round+1,A,U,V);
		A[V[round]]--;
		A[U[round]]--;

	}

}

void solve(){
	bt = 100;
    cin >> n >> m;
    for(int i = 1;i <= n;i++){

    	cin >> a[i];

    }

    for(int i = 1;i <= m;i++){

    	cin >> u[i] >> v[i];

    }

    dfs(1,a,u,v);

    cout << bt << endl;

}

int main(){

    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);

    int T;
    cin >> T;
    while(T--){

       solve();

    }

    return 0;
}
posted @ 2024-02-23 01:12  AlwaysBeShine  阅读(18)  评论(0)    收藏  举报