那天晚上和同学打球打的有点晚,结果就鸽了,现在来补一下
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=gcd(b1,b2…bi)d=gcd(b_1,b_2\dots b_i)d=gcd(b1,b2…bi)
时间复杂度O(n2logn)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
。分析可知这样一定能确定一个位置的数。总询问次数为2n−22n-22n−2次,即可原序列。
如果ai>aja_i>a_jai>aj,已知ai%aj=xa_i \%a_j= xai%aj=x和aj%ai=ya_j \%a_i= yaj%ai=y,分析可知a[j]=ya[j]=ya[j]=y即确定了一个位置的数。
如果ai<aja_i<a_jai<aj,已知ai%aj=xa_i \%a_j= xai%aj=x和aj%ai=ya_j \%a_i= yaj%ai=y,分析可知a[i]=xa[i]=xa[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]=min(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;
}
尝试采用单调栈维护一个单调序列不妨先考虑一种情况即max(hi+1,…,hj−1)<min(hi,hj)max(h_{i+1},…,h_{j−1})<min(h_i,h_j)max(hi+1,…,hj−1)<min(hi,hj),维护严格单调上升的序列,对于第iii个山峰考虑合法转移:对于单调栈中的元素如果第一个大于hih_ihi中的下标是pospospos那么f[pos−1]…f[tt]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;
}
要加油哦~