BestCoder Round #85

传送门:1001-sum  (前缀和取模)

题意:有n个数,问存不存在连续子序列之和是m的倍数

思路:

如果前缀和存在%m后==0的不用考虑,YES

如果存在余数为1~m-1的个数大于一个时我们也能保证为YES  为什么呢? 我们假设pre[1~i]%m为k,pre[1~j]%m为k(j>i)

那么容易想到pre[i+1,j]%m==0

#include <bits/stdc++.h>
#define Memset(x, a) memset(x, a, sizeof(x))
using  namespace  std;
const  int N=1e5+10;
int  n,m,T;
int  pre[N],vis[N];

inline int read()
{
  int x=0,f=1;char ch=getchar();
  while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
  return x*f;
}

int  main(){
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);

  T=read();
  while(T--){
    int x;
    Memset(vis,0);
    n=read();m=read();
    for(int i=1; i<=n ;i++){
      x=read();
      pre[i]=pre[i-1]+x;
      vis[pre[i]%m]++;
    }
    int flag=0;
    if(vis[0])flag=1;
    else{
      for(int i=1; i<=m; i++){
        if(vis[i]>=2){
          flag=1;break;
        }
      }
    }
    if(flag)cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
  }
  return 0;
}

传送门: 1002-domino    (贪心)

思路:肯定是距离越远,就越要用那k-1次去推,最后用1次把所有都推了就好了,所以是先sort一遍,倒着处理就好了。

#include<bits/stdc++.h>
#define ll __int64
using  namespace std;
int a[100010];

int  main(){
  std::ios::sync_with_stdio(false);
  std::cin.tie(0);
  int  T;
  cin>>T;
  while(T--){
    int  n,k;
    cin>>n>>k;
    for(int i=0; i<n-1; i++){
      cin>>a[i];
    }
    sort(a,a+n-1);
    ll  ans=0;
    for(int i=n-2; i>=0; i--){
      k--;
      if(k>=1)ans++;
      else ans+=a[i]+1;
    }
    ans++;
    cout<<ans<<endl;
  }
}

传送门:1003-abs

思路:

由于y质因数分解式中每个质因数均出现2次,那么y是一个完全平方数,设y=z*z,题目可转换成求z,使得每个质因数出现1次. 我们可以暴力枚举z,检查z是否符合要求,显然当z是质数是符合要求,由素数定理可以得,z的枚举量在logn级别 复杂度 O(

\sqrt[4]{n}log\sqrt[2]{n}4nlog2n

#include <bits/stdc++.h>
#define ll __int64
using  namespace  std;
const ll inf= 0x7fffffffffffffffLL;
ll  ans;
ll n;

bool  check(ll x){
  if(x<2)return  false;
  ll t=x;
  for(ll i=2; i*i<=x; i++){
    if(x%i==0){
      if(x%(i*i)==0)return  false;
      x/=i;
    }
  }
  ans=min(ans,abs(t*t-n));
  return true;
}

inline ll read()
{
  ll x=0,f=1;char ch=getchar();
  while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
  while(ch<='9'&&ch>='0'){x=x*10+ch-'0';ch=getchar();}
  return x*f;
}

int  main(){
  int T;
  scanf("%d",&T);
  while(T--){
    n=read();
    ll x=(ll)(sqrt(n)+0.5);
    ans=inf;
    int flag=0;
    for(int i=0; ; i++){
      if(check(x+i))flag=1;
      if(check(x-i))flag=1;
      if(flag)break;
    }
    printf("%I64d\n",ans);
  }
  return 0;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值