文章目录
- A. How Much Does Daytona Cost?
- 题意:
- 题解:
- 代码:
- B. Aleksa and Stack
- 题意:
- 题解:
- 代码:
- C. Vasilije in Cacak
- 题意:
- 题解:
- 代码:
- E. Iva & Pav
- 题意:
- 题解:
- 代码:
A. How Much Does Daytona Cost?
题意:
给出一个长度为 n n n的序列 a a a和一个数字 k k k。请你判断 a a a中是否存在一个非空子段使得 k k k在这个子段中出现的次数严格大于其它数字的出现次数。存在输出 Y E S YES YES,否则输出 N O NO NO。
题解:
若序列中存在k,即为 y e s yes yes,否则为 n o no no。
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define int long longusing namespace std;void solve(){int n,k;int flag=0;cin>>n>>k;for(int i=1;i<=n;i++){int x;cin>>x;if(x==k) flag=1;}if(flag) cout<<"YES"<<endl;else cout<<"NO"<<endl;
}
signed main(){int t;cin>>t;while(t--) solve();return 0;
}
B. Aleksa and Stack
题意:
每次构造一个数组,满足 ( 3 ∗ (3* (3∗a_{i+2} ) )%( )a_{i+1} + + +a_{i} ) ! = 0 )!=0 )!=0。
题解:
奇数 + 奇数 = 偶数 奇数+奇数=偶数 奇数+奇数=偶数, 奇数 ∗ 3 = 奇数 奇数*3=奇数 奇数∗3=奇数,奇数不能整除偶数,所以数组的构造方法就找到了。
代码:
#include<iostream>
#include<algorithm>using namespace std;const int N=2E5+10;
int a[N];void solve(){int n;cin>>n;a[1]=1;a[2]=3;for(int i=3;i<=n;i++) a[i]=a[i-1]+2;for(int i=1;i<=n;i++) cout<<a[i]<<" ";cout<<endl;
}
int main(){int t;cin>>t;while(t--) solve();return 0;
}
C. Vasilije in Cacak
题意:
给定n,k,x,问能否从1~n中选出k个数,使其和为x。
题解:
求出最大能构成的数字,以及最小能构成的数字,若x在区间内就为yes,否则为no。
代码:
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#define int long longusing namespace std;const int N=2e5+10;
int a[N];void solve(){int n,k,x;cin>>n>>k>>x;int xiao=k*(k+1)/2;int da=n*(n+1)/2-(n-k)*(n-k+1)/2;if(x>=xiao&&x<=da) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
signed main(){int t;cin>>t;while(t--) solve();return 0;
}
E. Iva & Pav
题意:
每组数据给定长度为 q 次询问。我们定义 f(l,r)(1≤l≤r≤n) 表示 a l a_{l} al& a l + 1 a_{l+1} al+1& a l + 2 a_{l+2} al+2&… a r − 1 a_{r-1} ar−1& a r a_{r} ar的结果。其中,&表示位与运算。对于每次询问,将给定 l,k。请你找到最大的 r 使得 f(l,r)≥k。如果无解,输出 -1。
题解:
数组 b i , j b_{i,j} bi,j,表示前i个数的第j位1的数量,因为1&1才为1,所以只有当前i个数的第j位都为1时相与才为1,然后用二分查询r。
代码:
#include<iostream>
#include<algorithm>#define int long longusing namespace std;const int N=2e5+10;
int a[N],b[N][33];void solve(){int n;cin>>n;for(int i=0;i<n;i++) cin>>a[i];for(int i=0;i<=n;i++)for(int j=0;j<=33;j++) b[i][j]=0;for(int i=0;i<n;i++)for(int j=0;j<30;j++){if(a[i]&(1<<j)) b[i+1][j]=b[i][j]+1;else b[i+1][j]=b[i][j];}int q;cin>>q;while(q--){int l,k;cin>>l>>k;if(a[l-1]<k){cout<<"-1"<<endl;continue;}int st=l,ed=n;while(st<ed){int mid=(st+ed+1)/2;int sum=0;for(int i=0;i<30;i++)if(b[mid][i]-b[l-1][i]==mid-l+1) sum+=(1<<i);if(sum<k) ed=mid-1;else st=mid;}cout<<st<<endl;}
}
signed main(){int t;cin>>t;while(t--) solve();return 0;
}