那天晚上和同学打球打的有点晚,结果就鸽了,现在来补一下
A - Ahahahahahahahaha
直接看原数组中0的个数cnt0
和1的个数cnt1
,谁多留谁即可,注意留1的时候要留偶数个。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
const int N=1010;
int a[N];
int n;
int main()
{
IO;
int T=1;
cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
int cnt0=0,cnt1=0;
for(int i=1;i<=n;i++)
{
if(a[i]) cnt1++;
else cnt0++;
}
if(cnt1<=n/2)
{
cout<<cnt0<<'\n';
for(int i=1;i<=cnt0;i++) cout<<0<<' ';
cout<<'\n';
}
else
{
if(cnt1&1) cnt1--;
cout<<cnt1<<'\n';
for(int i=1;i<=cnt1;i++) cout<<1<<' ';
cout<<'\n';
}
}
return 0;
}
B - Big Vova
直接暴力,从第一位开始每次选一个目前使c[i]
最大的数即可,维护d使之为
d
=
g
c
d
(
b
1
,
b
2
…
b
i
)
d=gcd(b_1,b_2\dots b_i)
d=gcd(b1,b2…bi)
时间复杂度
O
(
n
2
l
o
g
n
)
O(n^2logn)
O(n2logn)
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=1010;
int a[N],b[N],n;
int gcd(int a,int b)
{
return b?gcd(b,a%b):a;
}
int main()
{
IO;
int T=1;
cin>>T;
while(T--)
{
cin>>n;
int d=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
d=max(a[i],d);
}
for(int i=1;i<=n;i++)
{
int mx=0;
int p=-1;
for(int j=1;j<=n;j++)
{
if(a[j]==0) continue;//之前选过
if(mx<gcd(d,a[j]))
{
mx=gcd(d,a[j]);
p=j;
}
}
b[i]=a[p];
d=gcd(d,b[i]);
a[p]=0;
}
for(int i=1;i<=n;i++) cout<<b[i]<<' ';
cout<<'\n';
}
return 0;
}
C - Chocolate Bunny
交互题,第一次做什么东西啊
每次选择没有确定的两个位置i,j,询问i、j
和j、i
。分析可知这样一定能确定一个位置的数。总询问次数为
2
n
−
2
2n-2
2n−2次,即可原序列。
如果
a
i
>
a
j
a_i>a_j
ai>aj,已知
a
i
%
a
j
=
x
a_i \%a_j= x
ai%aj=x和
a
j
%
a
i
=
y
a_j \%a_i= y
aj%ai=y,分析可知
a
[
j
]
=
y
a[j]=y
a[j]=y即确定了一个位置的数。
如果
a
i
<
a
j
a_i<a_j
ai<aj,已知
a
i
%
a
j
=
x
a_i \%a_j= x
ai%aj=x和
a
j
%
a
i
=
y
a_j \%a_i= y
aj%ai=y,分析可知
a
[
i
]
=
x
a[i]=x
a[i]=x也能能够确定一个位置的数。
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=10010;
int a[N],n;
bool st[N];
int main()
{
IO;
int T=1;
//cin>>T;
while(T--)
{
cin>>n;
int x,y,now=1;
for(int i=2;i<=n;i++)
{
cout<<"? "<<now<<' '<<i<<'\n';cout.flush();cin>>x;
cout<<"? "<<i<<' '<<now<<'\n';cout.flush();cin>>y;
if(x>y)
{
a[now]=x;
st[x]=1;
now=i;
}
else
{
a[i]=y;
st[y]=1;
}
}
for(int i=1;i<=n;i++)
if(!st[i]) a[now]=i;
cout<<"! ";
for(int i=1;i<=n;i++) cout<<a[i]<<' ';
cout<<'\n';
}
return 0;
}
D - Discrete Centrifugal Jumps
f [ i ] = m i n ( f [ i ] , f [ k ] + 1 ) f[i]=min(f[i],f[k]+1) f[i]=min(f[i],f[k]+1) 对于 h [ k + 1 … i − 1 ] h[k+1\dots i-1] h[k+1…i−1]满足题目条件即可
// O(n^2)
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int N=300010;
int h[N],n;
int f[N];
int main()
{
IO;
int T=1;
//cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>h[i];
memset(f,0x3f,sizeof f);
f[1]=0;
for(int i=1;i<=n;i++)
{
int maxh=0,minh=0x3f3f3f3f;
for(int j=i-1;j;j--)
{
if(minh>max(h[i],h[j])||maxh<min(h[i],h[j]))
f[i]=min(f[i],f[j]+1);
minh=min(minh,h[j]);
maxh=max(maxh,h[j]);
}
}
cout<<f[n]<<endl;
}
return 0;
}
尝试采用单调栈维护一个单调序列不妨先考虑一种情况即 m a x ( h i + 1 , … , h j − 1 ) < m i n ( h i , h j ) max(h_{i+1},…,h_{j−1})<min(h_i,h_j) max(hi+1,…,hj−1)<min(hi,hj),维护严格单调上升的序列,对于第 i i i个山峰考虑合法转移:对于单调栈中的元素如果第一个大于 h i h_i hi中的下标是 p o s pos pos那么 f [ p o s − 1 ] … f [ t t ] f[pos-1]\dots f[tt] f[pos−1]…f[tt]都可以更新 f [ i ] f[i] f[i],在维护有序栈的同时更新不断更新答案即可
#define IO ios::sync_with_stdio(false);cin.tie();cout.tie(0)
#pragma GCC optimize(2)
#include<iostream>
#include<algorithm>
using namespace std;
const int N=300010;
int h[N],n;
int q1[N],tt1;
int q2[N],tt2;
int f[N];
int main()
{
IO;
int T=1;
//cin>>T;
while(T--)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>h[i];
q1[++tt1]=1,q2[++tt2]=1;
for(int i=2;i<=n;i++)
{
f[i]=f[i-1]+1;
while(tt1&&h[q1[tt1]]>h[i])
f[i]=min(f[q1[tt1--]]+1,f[i]);
if(tt1) f[i]=min(f[q1[tt1]]+1,f[i]);
while(tt1&&h[q1[tt1]]==h[i]) tt1--;
q1[++tt1]=i;
while(tt2&&h[q2[tt2]]<h[i])
f[i]=min(f[q2[tt2--]]+1,f[i]);
if(tt2) f[i]=min(f[q2[tt2]]+1,f[i]);
while(tt2&&h[q2[tt2]]==h[i]) tt2--;
q2[++tt2]=i;
}
cout<<f[n]<<'\n';
}
return 0;
}
要加油哦~