Codeforces998:ABCD-Round#493

(有任何问题欢迎留言或私聊 && 欢迎交流讨论哦

题目链接:传送门

(题面在最下面)

(ps:终于上蓝了啊)

A. Balloons

 A题的意思是把一个序列分成两部分,然后要求两部分的和不一样。
 每部分必须有至少一个数。

 当有解时,肯定有一种情况是这个人只选择一个数字,直接写就好了。
 (第一发用了sort,果然wa了一发,还好wa了,不然就sb了)

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1005;
const int INF = 0x3f3f3f3f;
const LL mod = 1000000007;
const double eps = 1e-8;
int n;
int ar[N];
int flag;
int main(){
  while(~scanf("%d",&n)){
    int sum=0;
    for(int i=0;i<n;++i){
      scanf("%d",&ar[i]);
      sum+=ar[i];
    }
    if(n==1){
      printf("-1\n");
      continue;
    }
    int p=-1;
    for(int i=n-1;i>=0;--i){
      if(ar[i]*2!=sum){
        p=i;
        break;
      }
    }
    if(p==-1){
      printf("-1\n");
    }else{
      printf("1\n%d\n",p+1 );
    }
  }
  return 0;
}

B. Cutting

 加一个隔板所需要的花费时左右数字的差的绝对值。问花费不超过k时,最多能插入多少费隔板。
 On枚举,记录奇数数字和偶数数字的数量,把可以插入隔板的位置的花费加入一个数组中。然后排序,从小到大选择,直到花费超过k即可。(注意k等于0是可以插花费为0的板子)

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1005;
const int INF = 0x3f3f3f3f;
const LL mod = 1000000007;
const double eps = 1e-8;
int n,k,t;
int ar[N],br[N];
int ab(int x){
  return x<0?-x:x;
}
int main(){
  while(~scanf("%d%d",&n,&k)){
    t=0;
    for(int i=0;i<n;++i){
      scanf("%d",&ar[i]);
    }
    int odd=0,even=0;
    for(int i=0;i<n;++i){
      if(ar[i]&1)odd++;
      else even++;
      if(odd==even&&odd>0&&i!=n-1){
        br[t++]=ab(ar[i]-ar[i+1]);
      }
    }
    sort(br,br+t);
    int cnt=0;
    for(int i=0;i<t;++i){
      if(k>=br[i]){
        cnt++;
        k-=br[i];
      }
    }
    printf("%d\n",cnt );
  }
  return 0;
}

C. Convert to Ones

 给一段01串,有两种操作,分别花费a,b。
 操作1:把一段序列倒置;操作2:把一段序列取相反数。
 问最少花费使得串全为1。

 预处理出0段和1段的个数。最少的花费肯定是在直接把0段执行操作2的花费 和 把所有的1段移到一段再操作2的花费之间。
 贪心证明。

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 300005;
const int INF = 0x3f3f3f3f;
const LL mod = 1000000007;
const double eps = 1e-8;
int n,k,t,a,b;
char s[N];
int ar[N],br[N];
int ab(int x){
  return x<0?-x:x;
}
int main(){
  while(~scanf("%d%d%d",&n,&a,&b)){
    scanf("%s",s);
    int flag=1;
    for(int i=0;i<n;++i){
      ar[i]=s[i]-'0';
      if(ar[i]==0)flag=0;
    }
    if(flag){
      printf("0\n");
      continue;
    }
    int sum=0,zero=0,one=0,last=ar[0];
    if(last==1)one++;
    else zero++;
    for(int i=1;i<n;++i){
      if(ar[i]!=last){
        if(ar[i])one++;
        else zero++;
        last=ar[i];
      }
    }
    LL ans=min(zero*1LL*b,(zero-1LL)*1LL*a+b);
    printf("%lld\n",ans );
  }
  return 0;
}

D. Roman Digits

 暴力搜索出1-15个罗马字母可以组成的数字的个数。
 做差后发现,当n>=12时,这是一个等差数列。
 然后最多不会超过50n(n<=1e9),所以不会爆longlong。

AC代码:

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 300005;
const int INF = 0x3f3f3f3f;
const int mod = 1000000007;
const double eps = 1e-8;
int n;
int ar[1000000+5],ans[N];
int az[6]={1,5,10,50};
void dfs(int num,int v,int t){
  if(num==t){
    ar[v]=1;
    return;
  }
  for(int i=0;i<4;++i){
    dfs(num+1,az[i]+v,t);
  }
}
int main(){
  int mm=0;
  for(int t=1;t<=12;++t){
    memset(ar,0,sizeof(ar));
    ar[0]=1;
    dfs(0,0,t);
    int sum=0;
    for(int k=1;k<=1000;++k){
      if(ar[k]){
        sum++;
        mm=max(mm,k);
      }
    }
    ans[t]=sum;
  }
  scanf("%d",&n);
  if(n<=12){
    printf("%d\n",ans[n] );
  }else{
    printf("%lld\n",ans[12]*1LL+(n-12)*1LL*49 );
  }
  return 0;
}

看到一个D题神仙代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstdint>
#include<climits>
#include<numeric>
#include<bitset>
#include<stack>
#include<set>
#include<queue>
#include<map>
#include<cctype>
#include<string>
#include<cmath>
#include<cstring>
#include<iomanip>
#include<unordered_set>
#include<functional>
#include<iterator>
using namespace std;
long long n, wynik;
int32_t main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    for (int i = 0; i < 9; i++){
        for (int j = 0; j <= (i < 5 ? 8 : 0); j++){
            if (n - i - j >= 0) wynik += (n - i - j + 1);
        }
    }
    cout << wynik << endl;
    getchar();
    getchar();
    return 0;
}

题面:

这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述
这里写图片描述

猜你喜欢

转载自blog.csdn.net/qq_39599067/article/details/80879329