牛客小白66 A-F

A.先交换

思维:给你一个数组和一种无限次数的操作,问你操作多少次能把a1变成奇数

做法:根据题意模拟即可,只有三种可能 要么 为0 要么为 1 要么不存在

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
using namespace std;
#define rall(x) (x).rbegin(), (x).rend()
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define sz(a) (int) (a).size()
#define endl "\n"
void solved() {
int n;
cin>>n;
vector<int> a(n+1);
int idx=-1;
for(int i=1;i<=n;i++){
	cin>>a[i];
}
if(a[1]%2==1){
	cout<<0<<endl;
	return ;
} 
for(int i=2;i<=n;i++){
	if(a[i]<a[1]&&a[i]%2==1){
		idx=i;
		break;
	}
}
if(idx>1){
	cout<<1<<endl;
	
}
else{
	cout<<-1<<endl;
}

}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int t;
	cin >> t;
	while (t--) {
		solved();
	}
	return 0;

}


B.再交换

思维/构造 思路:只需要逐位对比A,B,第一次位数不同时,如果A大于B那么交换A和B的这一位,如果B大于A那么直接交换第一位或者最后一位(要注意相等的位置不能在这二位还取这二位)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
using namespace std;
#define rall(x) (x).rbegin(), (x).rend()
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define sz(a) (int) (a).size()
#define endl "\n"
void solved() {
int n;
cin>>n;
string a,b;
cin>>a>>b;
for(int i=0;i<n;i++){
  if(a[i]!=b[i]){
  	if(b[i]>a[i]){
	 if(i>0){
	 	cout<<i-1+1<<" "<<i-1+1<<endl;
	 	
	 }
	 else cout<<i+1+1<<" "<<i+1+1<<endl;
	  return ;
	  }
	  else{
	  	cout<<i+1<<" "<<i+1<<endl;
	  	return ;
	  }
  }
}
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int t;
	cin >> t;
	while (t--) {
		solved();
	}
	return 0;

}


C.空洞骑士

思维/贪心:
可以明确一点,初始位置s只可能在三种地方,第一个金币左边,最后一个金币右边,或者在中间为最优的,根据题意讨论即可

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
using namespace std;
#define rall(x) (x).rbegin(), (x).rend()
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define sz(a) (int) (a).size()
#define endl "\n"
void solved() {
int n;
cin>>n;
string a,b;
cin>>a>>b;
for(int i=0;i<n;i++){
  if(a[i]!=b[i]){
  	if(b[i]>a[i]){
	 if(i>0){
	 	cout<<i-1+1<<" "<<i-1+1<<endl;
	 	
	 }
	 else cout<<i+1+1<<" "<<i+1+1<<endl;
	  return ;
	  }
	  else{
	  	cout<<i+1<<" "<<i+1<<endl;
	  	return ;
	  }
  }
}
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int t;
	cin >> t;
	while (t--) {
		solved();
	}
	return 0;

}


D.障碍

枚举优化:

思路:很容易想到的一种思路是枚举x,然后将其对每一个隔壁进行计算。可以想到的是x最多只有500,所以考虑枚举x对于每个隔壁的值,最后取最大即可

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
using namespace std;
#define rall(x) (x).rbegin(), (x).rend()
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define sz(a) (int) (a).size()
#define endl "\n"
void solved() {
int n,m;
cin>>n>>m;
vector<int> a(m+2);
for(int i=1;i<=m;i++){
	cin>>a[i];
}
a[m+1]=n;
LL ans=1;
for(int i=0;i<=m;i++){
	for(int j=0;j<=500;j++){
		int r=i+j+1;
		if(r>m+1) break;
		LL res=a[r]-a[i]-j*j;
		ans=max(ans*1LL,res);
	}
}
cout<<ans<<endl;

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

}


E.生成树与路径

图论/构造:

首先来说最小生成树和最短路路是容易确定的,就是从1到n进行线性连接即可,关键是如何满足在加边的情况下仍然保留他们

考虑如何破坏最短路:当1不通过到 2,3,4,....i-1时的距离大于直接到i的距离时那么最短路就会被破坏,所以我们从小开始考虑,1 到 3 ,2 到 4,3 到 5.,1 到 4 2 到 5....这样的距离,贪心的考虑,因为间隔点越多需要的边就越长,所以我们把短边用在相隔点较少的地方,把长边用在点较多的地方

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
using namespace std;
#define rall(x) (x).rbegin(), (x).rend()
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define sz(a) (int) (a).size()
#define endl "\n"
void solved() {
int n,m;
cin>>n>>m;
int i=1;
int t =1;
while(i<=m){
	for(int j=1;j<n;j++){
	if(j+t>n||i>m) break;	
		cout<<j<<' '<<j+t<<' '<<i++<<endl;
	}
	t++;
}
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout.tie(nullptr);
	int t;
	cin >> t;
	while (t--) {
		solved();
	}
	return 0;

}


F.球球大作战:
贪心+二分答案

1.通过模拟过程可以发现,从最大值依次比到最小值是最优的

2.如果X可以,那么大于X的一定可以,具有单调性,我们考虑二分答案

那么时间复杂度就是O(nlogn)的

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
using namespace std;
#define rall(x) (x).rbegin(), (x).rend()
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define sz(a) (int) (a).size()
#define endl "\n"
const int N=1e5+10;
LL a[N],b[N];
int n;
bool check(LL x){
LL minn=a[n];
for(int i=n-1;i>=1;i--){
if(i!=x)	minn=(minn+a[i])/2;
}
return a[x]>=minn;


}
void solved() {
cin>>n;

for(int i=1;i<=n;i++) cin>>a[i],b[i]=a[i];
sort(a+1,a+n+1);
int l=1,r=n;
while(l<r){
	LL mid=(l+r)>>1;
	if(check(mid)) r=mid;
	else l=mid+1;
}
string ans="";
for(int i=1;i<=n;i++){
 if(b[i]>=a[l]) ans+='1';
 else ans+='0'; 
}

cout<<ans<<endl;

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

}


总结:
1.在求解问题时,考虑暴力优化 ,注意观察问题的性质能否给题目带来化简

2.当你觉得题目很难时,或者没用思路时,可以看看自己是不是把题目想复杂了,可以考虑暴力或者手算样例积攒思路

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
牛客 a卷2022年第四季度的华为题目中,要求考生设计一种高效的数据结构,能够支持以下几种操作: 1. 添加一个元素 2. 删除一个元素 3. 查找是否存在某个元素 4. 返回元素的总数 该数据结构要求满足空间复杂度较小、时间复杂度较低、能够快速地进行查找和修改等多种操作。 想要编写这样一种数据结构,我们可以参考许多已有的经典算法数据结构,如二叉树、哈希表、红黑树等,通过综合利用它们的优点来实现这个问题的解决。 例如,我们可以通过哈希表来存储所有元素的值,并在每个哈希链表的元素中再使用红黑树来进行排序与查找。这样,我们既能够轻松地进行元素的添加和删除操作,也能够在查找较大数据范围和数量时保持较高的速度与效率。同时,由于使用了多个数据结构来协同完成这个问题,我们也能够在空间复杂度上适度地进行优化。 当然,在具体设计这个数据结构的过程中,我们还需要考虑一些实践中的细节问题,例如如何避免哈希冲突、如何处理数据丢失与被删除元素所占用的空间等问题,这都需要相应的算法与流程来进行处理。 总体来看,设计这种支持多种操作的高效数据结构,需要我们具备丰富的算法知识和编程实践能力,同时需要我们在具体处理问题时能够将多种算法数据结构进行有效地结合。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值