A
乍一看,找一个数不是数组内所有数的倍数,或者因数
但是换个角度想,如果这个数的因数,都没有这些数,且这个数比数组内的所有数都大
那么很容易想到,1e9+7,直接输出即可
B
一棵树上,不重不漏地经过每一个点,那么这样一棵树必然是一条链
所以只用考虑每个节点的“度”
D
判断数组内是否只出现两个数且数量相等,按照题意模拟即可
#include<bits/stdc++.h>
using namespace std;
int t;
int n;
map<int,int>mp;
void solve(){
cin>>n;
int cnt=0;mp.clear();
for(int i=1;i<=n;++i){
int x;
cin>>x;
if(mp[x]==0) ++cnt,mp[x]++;
else mp[x]++;
}
if(cnt!=2){
puts("No");
}
else {
int last=0;
for(auto [x,y]:mp){
if(last==0) last=y;
else{
if(last!=y) puts("No");
else puts("Yes");
}
}
}
return ;
}
int main(){
cin>>t;
while(t--){
solve();
}
return 0;
}
G
可以对数组内的数,选一个+1,选一个-1,其实就是转移值罢了
所以如果数组内的数的和不等于一个排列的总和,那就不能形成一个排列
贪心地想,每个数变成离他最近的(1-n)之间的数
先排序,那么答案
\(ans=sum_{i=1}^{n}|a_i-i|\)
ans/=2,因为是转移值
#include<bits/stdc++.h>
using namespace std;
#define ll long long
int n;
int top=0;
const int maxn=1e5+10;
ll sum=0;
int a[maxn];
int f[maxn];
bool book[maxn];
int main(){
cin>>n;
for(int i=1;i<=n;++i){
cin>>a[i];
sum+=a[i];
if(a[i]<=n && a[i]>=1 && !book[a[i]])book[a[i]]=1;
else f[++top]=a[i];
}
if(sum!=(ll)n*(1+n)/2){
puts("-1");
}
else{
ll ans=0;
int j=1; sort(f+1,f+1+top);
for(int i=1;i<=top;++i){
while(book[j]==1 && j<=n) ++j;
ans+=abs(j-f[i]);
}
cout<<ans/2<<endl;
}
return 0;
}
M
贪心地想,我们将最小值翻倍,然后算极差,但是可能最小值翻倍后比最大值还大,那么我们就需要考虑翻倍次小值
以此类推,从最小值开始,然后将扩张的区间扩张到次小值,最后到最大值
这样的扩张每个元素只会计算一次,时间复杂度O(n)
扩张的时候用set维护,当前数组的翻倍的区间,和未翻倍的区间,在每次扩张到一个最小值时,计算极差
#include <bits/stdc++.h>
using namespace std;
const int maxn= 1e5 + 5;
typedef long long ll;
struct node{
ll val,p;
}f[maxn];
bool cmp(node x,node y){
return x.val<y.val;
}
void solve()
{
int n;
cin>>n;
set<ll>st1,st2;
vector<ll>a(n+1);
for(int i=1;i<=n;i++){
cin>>f[i].val;
f[i].p=i;
a[i]=f[i].val;
st2.insert(f[i].val);
}
sort(f+1,f+1+n,cmp);
if(n==1){
cout<<0<<endl;
return ;
}
ll maxx=max(f[n].val,f[1].val*2),minn=1e15;
ll ans=maxx-min(f[1].val*2,f[2].val);
st1.insert(f[1].val*2);
st2.erase(f[1].val);
int l=f[1].p,r=f[1].p;
for(int i=2;i<=n;i++){
while(f[i].p>r){
r++;
st1.insert(a[r]*2);
st2.erase(a[r]);
}
while(f[i].p<l){
l--;
st1.insert(a[l]*2);
st2.erase(a[l]);
}
if(st1.size()&&st2.size()){
maxx=max(*st1.rbegin(),*st2.rbegin());
minn=min(*st1.begin(),*st2.begin());
ans=min(ans,maxx-minn);
}
else ans=min(ans,*st1.rbegin()-*st1.begin());
}
cout<<ans;
}
int main()
{
cin.tie(0);
cout.tie(0);
int t = 1;
while (t--)
solve();
return 0;
}
标签:val,2025,int,ll,++,else,牛客,maxn,集训营
From: https://www.cnblogs.com/guiyou/p/18688718