2021安徽省程序设计大赛网络预选赛 题解

A.最美合数

思路:预处理处理每个数多少个因数,遍历a到b找最大的即可。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e6+3;
#define fi first
#define se second
#define pb push_back
#define wzh(x) cerr<<#x<<'='<<x<<endl;
int cnt[N];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  for(int i=1;i<N;i++){
    for(int j=i;j<N;j+=i){
      cnt[j]++;
    }
  }
  int l,r;
  cin>>l>>r;
  int pre=0,ans;
  for(int i=l;i<=r;i++){
    if(cnt[i]>pre){
      pre=cnt[i];
      ans=i;
    }
  }
  cout<<pre<<'\n';
  return 0;
}

B.区间重叠

思路:差分维护每个点被覆盖的次数,找到覆盖最多的即可。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e7+3;
#define fi first
#define se second
#define pb push_back
#define wzh(x) cerr<<#x<<'='<<x<<endl;
int cnt[N];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int k;cin>>k;
  for(int i=1;i<=k;i++){
    int l,r;
    cin>>l>>r;
    cnt[l]++;cnt[r]--;
  }
  int ans=0;
  for(int i=1;i<N;i++)cnt[i]+=cnt[i-1],ans=max(ans,cnt[i]);
  cout<<ans<<'\n';
  return 0;
}

C.超级幂积

思路:快速幂

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 5e6+3;
#define fi first
#define se second
#define pb push_back
#define wzh(x) cerr<<#x<<'='<<x<<endl;
char a[N];
const int mod=1e9+7;
int add(int x,int y){
  x+=y;
  if(x>=mod)x-=mod;
  if(x<0)x+=mod;
  return x;
}
int mul(int x,int y){
  return 1ll*x*y%mod;
}
int sub(int x,int y){
  x=x+mod-y;
  if(x>=mod)x-=mod;
  return x;
}
int ksm(int x,int y,int z=1){
  for(;y;y>>=1,x=mul(x,x))if(y&1)z=mul(z,x);
  return z;
}
int fac[N],inv[N];
void P(){
  fac[0]=1;
  for(int i=1;i<N;i++)fac[i]=mul(fac[i-1],i);
  inv[N-1]=ksm(fac[N-1],mod-2);
  for(int i=N-2;i>=0;i--)inv[i]=mul(inv[i+1],i+1);
}
int di(int x,int y){
  return mul(x,ksm(y,mod-2));
}
LL C(int x,int y){
  if(x<y)return 0;
  return mul(fac[x],mul(inv[y],inv[x-y]));
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin>>a+1;
  int n=strlen(a+1);
  int ans=1;
  for(int i=1;i<=n;i++){
    ans=mul(ans,ksm(a[i]-'0',i));
  }
  cout<<ans<<'\n';
  return 0;
}

D.最优负载

思路:二分。注意下界要>=最大货物的重量

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e6+2;
#define fi first
#define se second
#define pb push_back
#define wzh(x) cerr<<#x<<'='<<x<<endl;
int n,k;
LL a[N];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin>>n>>k;
  for(int i=1;i<=n;i++)cin>>a[i];
  LL l=1,r=1e11,ans=1;
  while(l<=r){
    LL mid=l+r>>1;
    int cost=0;
    for(int i=1,j;i<=n;i=j+1){
      if(a[i]>mid){
        cost=k+1;
        break;
      }
      j=i;
      LL res=a[i];
      
      while(j+1<=n && 0ll+res+a[j+1]<=mid)j++,res+=a[j];
      cost++;
    }
    if(cost<=k)ans=mid,r=mid-1;
    else l=mid+1;
  }
  cout<<ans<<'\n';
  return 0;
}

E.最小重组木棍

思路:贪心,枚举每一位最大能放的,check的话,因为火柴棒是一个区间[2,7],所以只要在区间内的都能构成。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1e5+3;
#define fi first
#define se second
#define pb push_back
#define wzh(x) cerr<<#x<<'='<<x<<endl;
int A[10]={6,2,5,5,4,5,6,3,7,6};
int n,t;
char a[N],ans[N];
int can(int x,int y){
  if(x*2<=y && x*7>=y)return 1;
  return 0;
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  for(cin>>t;t;t--){
    cin>>n>>a+1;
    int tot=0;
    for(int i=1;i<=n;i++)tot+=A[a[i]-'0'];
    for(int i=1;i<=n;i++){
      for(int j=9;j>=0;j--){
        if(can(n-i,tot-A[j])){
          ans[i]=(j+'0');
          tot-=A[j];
          break;
        }
      }
    }
    ans[n+1]='\0';
    cout<<ans+1<<'\n';
  }
  return 0;
}

F.区间异或

思路:转化题目就是 多少区间,区间内每个二进制位在区间内仅出现一次。

用pre表示每个二进制位上一次出现的位置,L表示每个位置为右端点的最小左端点的位置。

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 2e6;
#define fi first
#define se second
#define pb push_back
#define wzh(x) cerr<<#x<<'='<<x<<endl;
int n,a[N];
int last[40],L[N];
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  cin>>n;
  LL ans=0;
  L[0]=1;
  for(int i=1;i<=n;i++)cin>>a[i];
  for(int i=1;i<=n;i++){
    int pre=L[i-1];
    for(int j=0;j<=30;j++){
      if(1ll<<j & a[i]){
        pre=max(pre,last[j]+1);
        last[j]=i;
      }
    }
    L[i]=max(L[i-1],pre);
    ans+=i-pre+1;
  }
  cout<<ans<<'\n';
  return 0;
}

G.最小乘积

因为只有5个数,所以直接全排列…

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<cmath>
#include<map>
#include<stack>
#include<vector>
#include<queue>
#include<set>
#include<algorithm>
#include<iomanip>
#define max(a,b)   (a>b?a:b)
#define min(a,b)   (a<b?a:b)
#define swap(a,b)  (a=a+b,b=a-b,a=a-b)
#define e  2.718281828459045
#define INF 0x3f3f3f3f
#define PI acos(-1)
#define eps 1.0e18
#define lowbit(x) (x&(-x))
#define read(x) scanf("%d",&x)
#define put(x) printf("%d\n",x)
#define memset(x,y) memset(x,y,sizeof(x))
#define Debug(x) cout<<x<<" "<<endl
#define lson i << 1,l,m
#define rson i << 1 | 1,m + 1,r
#define rep(x,y,z) for(int x = y; x <= z; x++)
#define per(x,y,z) for(int x = y; x >= z; x--)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
ll gcd(ll a,ll b){return b?gcd(b,a%b):a;}
ll lcm(ll a,ll b){return a/gcd(a,b)*b;}
ll qpow(ll a,ll b,ll mod){ll res = 1;while(b){if(b&1){res=res*a%mod;}b>>=1;a=a*a%mod;}return res%mod;}
const ll mod = 1e9+7;
const int maxn = 2e5+5;
int a[5];
int main()
{
    ios::sync_with_stdio(false);    
    for(int i = 0; i < 5; i++){
        cin>>a[i];
    }
    sort(a,a+5);
    ll ans = 1e18;
    while(next_permutation(a,a+5)){
        ll cnt1 = a[0]*10+a[1];
        ll cnt2 = a[2]*100+a[3]*10+a[4];
        if(cnt1<10||cnt2<100)continue;
        ans = min(cnt1*cnt2,ans);
    }
    cout<<ans<<endl;
    
    return 0;
}
  • 2
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值