A. Dual Trigger
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
int n;
string s;
void solve() {
cin>>n;
cin>>s;
int cnt=0;
for(int i=0;i<n;i++){
if(s[i]=='1') cnt++;
}
if(cnt==2){
for(int i=0;i<n-1;i++){
if(s[i]=='1'&&s[i+1]=='1'){
cout<<"NO"<<endl;
return;
}
}
}
if(cnt%2) cout<<"NO"<<endl;
else cout<<"YES"<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
cin>>t;
while(t--) {
solve();
}
return 0;
}
B. Battle Cows
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=1e5+10;
int a[N];
int n,k;
void solve() {
cin>>n>>k;
for(int i=1;i<=n;i++) cin>>a[i];
int maxn=0;
for(int i=1;i<=k-1;i++){
maxn=max(maxn,a[i]);
}
//不换
int ans1=0;
if(a[k]<maxn) ans1=0;
else{
if(k!=1) ans1++;
for(int i=k+1;i<=n;i++){
if(a[k]>a[i]) ans1++;
else break;
}
}
//和第二个换
int ans2=0;
swap(a[k],a[2]);
maxn=0;
for(int i=1;i<=2-1;i++){
maxn=max(maxn,a[i]);
}
if(a[2]<maxn) ans2=0;
else{
ans2++;
for(int i=2+1;i<=n;i++){
if(a[2]>a[i]) ans2++;
else break;
}
}
swap(a[2],a[k]);
//和比它大的第一个换
int ans3=0;
int pos=-1;
for(int i=1;i<=n;i++){
if(a[i]>a[k]){
pos=i;
break;
}
}
if(pos!=-1) {
swap(a[k],a[pos]);
maxn=0;
for(int i=1;i<=pos-1;i++){
maxn=max(maxn,a[i]);
}
if(a[pos]<maxn) ans3=0;
else{
if(pos!=1) ans3++;
for(int i=pos+1;i<=n;i++){
if(a[pos]>a[i]) ans3++;
else break;
}
}
}
cout<<max({ans1,ans2,ans3})<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
cin>>t;
while(t--) {
solve();
}
return 0;
}
C. Ticket Hoarding
参考Codeforces Global Round 25 A-F - 知乎 (zhihu.com)
如果有多个条件限制的话,那么一个一个考虑,先考虑限制简单的条件,然后一个一个往上加
首先,如果不考虑票价增长这一条件,那么肯定是买票价低的,而且尽可能买满m张票
然后加上票价增长这一条件,我们之后所选择的单价都会增加,比如说前面买了x张,那么后面买的单价增加x,发现实际上增加的票价和原先买票的价钱是独立的,只不过每次增加了当前票买的张数*前面买的票的总张数,发现式子中只有张数,并没有票价,所以和买的票的顺序无关,只和每次买的张数有关,所以优先买票价低的,然而我们肯定每次尽可能买的多,因为前面票价低,这是直观上的感觉
如果分析的时候可以定量的话,那么就定量分析:
现在就是看如何分配每次买的票的张数最优,对不同情况进行定量分析比较,看哪种更优
如果我们每次一张一张买的话,那么增量是1+2+…+k-1=k * (k-1)/2
如果我们第一次买x张的话,后面一张一张买的话,那么增量是x+(x+1)+(x+2)+…+(x+k-x-1)=x * (k-x)+1+2+…+k-x-1=x * (k-x)+(k-x)*(k-x-1)/2=(k-x) * (k+x-1)/2=k * (k-1)/2-x * (x-1)/2
比较一下,发现增量是减了x * (x-1)/2
所以优先买票价低的,并且每次尽可能买的多
trick:
1.如果有多个条件限制的话,那么一个一个考虑,先考虑限制简单的条件,然后一个一个往上加
2.如果分析的时候可以定量的话,那么就优先定量分析
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
const int N=3e5+10;
int a[N];
int n,m,k;
void solve() {
cin>>n>>m>>k;
for(int i=1;i<=n;i++) cin>>a[i];
sort(a+1,a+1+n);
int cnt=0;
int ans=0;
for(int i=1;i<=n;i++){
int count=min(m,k);
ans+=a[i]*count;
ans+=cnt*count;
cnt+=count;
k-=count;
if(k==0) break;
}
cout<<ans<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
cin>>t;
while(t--) {
solve();
}
return 0;
}
D. Buying Jewels
首先如果n小于k,肯定无解
如果n等于k,那么只要一个商店,价格定为1
构造题,我们可以这样构造, 两个商店,第二个商店价格定为1,让它刚好剩余价钱为k-1,那么就可以买到k-1个
那么就让第一个商店花的钱为n-(k-1)=n-k+1,但是必须保证n/(n-k+1)==1,这样,总共刚好可以买到k个
此时,n%(n-k+1)=k-1==>n-k+1>k-1==>k<(n+2)/2
否则,如果不满足以上条件,那么k大概接近或超过n的一半了,那么肯定价格不能定为3及以上了,只能定为1或者2了,进行验证即可
参考Codeforces Global Round 25 A - F - 知乎 (zhihu.com)
实际上,最后一种情况无解,具体证明见Codeforces Global Round 25(A-E)-CSDN博客
#include<bits/stdc++.h>
#define endl '\n'
#define int long long
using namespace std;
int n,k;
bool check(vector<int>a){
int total=0;
int sum=n;
for(auto x:a){
total+=sum/x;
sum%=x;
}
if(total==k){
cout<<"YES"<<endl;
cout<<a.size()<<endl;
for(auto x:a) cout<<x<<' ';
cout<<endl;
return true;
}
return false;
}
void solve() {
cin>>n>>k;
if(n<k){
cout<<"NO"<<endl;
return;
}
if(n==k){
cout<<"YES"<<endl;
cout<<1<<endl;
cout<<1<<endl;
return;
}
int next=k-1;
if(n/(n-next)==1){
cout<<"YES"<<endl;
cout<<2<<endl;
cout<<n-k+1<<' '<<1<<endl;
return;
}
if(!check({2,1})&&!check({2})&&!check({1})) cout<<"NO"<<endl;
}
signed main() {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t=1;
cin>>t;
while(t--) {
solve();
}
return 0;
}