牛客寒假算法集训5-总结
1.C++内存四区2.算法-排序-快速排序3.算法-排序-归并排序4.c++重载5.算法-二分6.算法—前缀和7.算法—差分8.算法-双指针9.c++引用10.c++函数默认参数及占位参数11.c++函数模板12.c++类和对象-封装13.struct和class的区别14.成员属性设置为私有15.C++类和对象-对象特性(1)16.C++类和对象-对象特性(2)17.N皇后18.动态规划dp-01背包问题19.C++类和对象-对象特性(4)20.C++类和对象-对象特性(3)21.C++友元22.C++运算符重载23.C++继承24.C++多态25.C++类模板26.C++vector容器27.C++string容器28.C++deque容器29.算法-树状数组30.算法线段树31.算法-bfs32.算法-贪心33.算法-Flood Fill34.数据结构-链表35.数据结构-栈36.数据结构-队列37.P2678 跳石头38.5132139.54440.3213241.牛客寒假算法集训1-总结42.牛客寒假算法集训2-总结43.牛客寒假算法集训3-总结44.数论-质数45.博弈论46.第十四届蓝桥杯省赛C++题解47.Trie树48.并查集49.数据结构-堆50.哈希表51.拓扑排序52.Dijkstra53.spfa54.数论-约数55.数论-欧拉函数56.图的存储和遍历57.牛客寒假算法集训4-总结
58.牛客寒假算法集训5-总结
59.牛客寒假算法集训6-总结60.Bellman_ford61.Floyd62.编辑距离63.数位dpA
时间复杂度:
O(n)
AC代码:
#include <iostream>
using namespace std;
int n,cnt;
int a[110];
bool is_isprime(int x)
{
if(x<2) return false;
for(int i=2;i<=x/i;i++)
if(x%i==0) return false;
return true;
}
int main()
{
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i];
if(a[i]==1) continue;
if(is_isprime(a[i])) cnt++;
else cnt++;
}
cout<<cnt;
return 0;
}
B
思路:
在两个数字之间插入x个0,可以等效为这两个数字同时减去x
时间复杂度:
O(n)
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
typedef long long ll;
ll n,cnt;
ll a[N];
ll x;
ll sum;
ll q,y;
int main()
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=0,j=0;i<=n;i++,j++)
{
if(i==0)
{
x=a[1];
cnt+=x-1;
q=cnt;
continue;
}
if(i==n) y=a[n];
else y=min(a[i],a[i+1]);
int p=y-1;
sum+=a[i];
if(y==1) continue;
ll res=p+q+j;
if(sum/res>=1)
{
cnt+=p;sum=0;q=p;j=0;
}
else
{ if(sum-q-j<=p)
{
cnt+=sum-q-j;
q=sum-q-j;
sum=0;
j=0;
}
}
}
cout<<cnt;
return 0;
}
I
思路:
简单模拟,签到题
时间复杂度:
O(1)
AC代码:
#include <iostream>
#include <cmath>
using namespace std;
typedef long long ll;
ll t,a,k,d;
ll s;
ll l,r;
bool p;
int main()
{
cin>>t>>a>>k;
if(t<0)
{
s=0;
int l=-k,r=k;
while(s>=t)
{
if(a>=l&&a<=r)
{
d+=abs(a-s);
d+=abs(t-a);
p=true;
break;
}
s--;l--;r--;d++;
}
if(!p)
{
s++;d--;
d+=abs(s-a)*2;
}
}
else if(t==0) d=abs(s-a);
else
{ s=0;
int l=-k,r=k;
while(s<=t)
{
if(a>=l&&a<=r)
{
d+=abs(a-s);
d+=abs(t-a);
p=true;
break;
}
s++;l++;r++;d++;
}
if(!p)
{
s--;d--;
d+=abs(s-a)*2;
}
}
cout<<d;
return 0;
}
L
思路:
枚举
时间复杂度:
o(1)
AC代码:
#include <iostream>
using namespace std;
const int N=1010;
int n,x,cnt,res;
int main()
{
cin>>n>>x;
cnt=(n+x)/2;
res=n-cnt;
if(cnt-res!=x) cout<<-1;
else cout<<cnt<<' '<<res;
return 0;
}
M
思路:
一个很重要的思路:当可以通过删除操作得到两个以上连通块时,最多只需要两次删除操作;
比如:
a:1 2 3 4 5 6
b:4 5 6 1 3 2
随意找两个处于相同位置的数字,比如数组a中,3在第三列,数组b中,6也在第三列,那么只需要删去3和6就能得到两个以上连通块;
另外,若使用a[x]表示数字x在数组a上的位置,用b[x]表示数字x在数组b上的位置,那么我们知道:当时,似乎只需要一次操作就能将原来的排列分成两个连通块;
但是需要注意一点:当时,可能会是这种情况:
1 2 3 4
1 3 2 4
故此时需要进行特判(判断是否在头部或者尾部);
至于什么情况下输出-1,简单思考后,我们可以知道只有两种情况:
(1)n==1时
(2)n==2且数组a和b相同时
时间复杂度:
O(∑n)
AC代码:
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int T;
bool k;
int n;
int a[N],b[N];
int main()
{
cin>>T;
while(T--)
{
cin>>n;k=false;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=1;i<=n;i++) cin>>b[i];
if(n==1) cout<<-1<<endl;
else if(n==2)
{
for(int i=1;i<=2;i++)
{
if(a[i]==b[i]) {cout<<-1<<endl;k=true;break;}
}
if(!k) cout<<1<<endl;
}
else
{
for(int i=2;i<=n-1;i++)
{
if(a[i]==b[i]) {cout<<1<<endl;k=true;break;}
if(a[i]==b[i-1]) {cout<<1<<endl;k=true;break;}
if(a[i]==b[i+1]) {cout<<1<<endl;k=true;break;}
}
if(!k)
{
if(a[1]==b[2]||a[n]==b[n-1]) cout<<1<<endl;
else cout<<2<<endl;
}
}
}
return 0;
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 在鹅厂做java开发是什么体验
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析