牛客练习赛111 A—D

A明显的进位的就是遍历最低位

我们只需要从最后面开始往前走找到不是0的就可以了,统计0的个数然,找到不是0的直接用10-去这个数就可以了

// 数学公式要变形
// 莫急莫急先读题
#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x&(-x))
#define endl "\n"
#define ios ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
#define LF(x)   fixed<<setprecision(x)// c++ 保留小数
typedef long long LL;
typedef pair<int,int> PII;
typedef unsigned long long ULL;
const int N=1000010,M=1010,F=2*N,INF=0x3f3f3f3f,pp=133331;
const double pai=acos(-1.0);// pai
map<int,int> q;
int t,n,m;
string s;
void solve()
{
    cin>>s;
    reverse(s.begin(),s.end());
    n=s.size();
    int ans=0,cnt=0,f=0;
    for(int i=0;i<n;i++){
        if(s[i]=='0') cnt++;
        else {
            f=s[i]-'0';
            break;
        }
    }
    ans=pow(10,cnt)*(10-f);
    cout<<ans<<endl;
    
        return ;
}

int main ()
{
    ios// 不能有printf puts scanf
    cin>>t;
    while(t--)
    solve();
    return 0;
}

 直接结合样例就很简单了

B题看起来十分简单其实暗藏玄机

只需一句话你就明白了当a==b的时候,如果a中有重复字母那也可以交换

比如    aac   aac

这是yes 而   abc  abc 由于无法一次交换 所以无解

这件事情告诉我们看到不是合理的简单题不要太急,特别是注意看榜,有很多人错了就一定要再多思考

// 数学公式要变形
// 莫急莫急先读题
#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x&(-x))
#define endl "\n"
#define ios ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
#define LF(x)   fixed<<setprecision(x)// c++ 保留小数
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
const int N=1000010,M=1010,F=2*N,INF=0x3f3f3f3f,pp=13331;
const double pai=acos(-1.0);// pai
int t,n,m;
string a,b;
int c[30];
void solve()
{
    cin>>n>>a>>b;
    int l=0,r=0,cnt=0;
    for(int i=0;i<n;i++){
        if(a[i]!=b[i]&&!cnt) l=i;
        if(a[i]!=b[i]&&cnt) r=i;
        if(a[i]!=b[i]) cnt++;
    }
    for(int i=0;i<n;i++){
        c[a[i]-'a']++;
    }
    if(a==b){
        for(int i=0;i<26;i++){
            if(c[i]>=2)
            {
                cout<<"YES"<<endl;
                return ;
            }
        }
        cout<<"NO"<<endl;
        return ;
    }
    if(cnt!=2){
        cout<<"NO"<<endl;
        return ;
    }
    
    if(cnt==2){
        swap(a[l],a[r]);
        if(a==b){
            cout<<"YES"<<endl;
            return ;
        }
        cout<<"NO"<<endl;
    }
        return ;
}
// 万事读题为先
int main ()
{
    ios// 不能有printf puts scanf
    solve();
    return 0;
}

 C题对式子推导

 对kx<=m 时ky<=m  以及 kx>m时ky>m这个式子进行变形

对这个式子变形之后可以解出 kx<=m 时k的值  k=m/x这个同时 是分界线 那么大于的就是k+1

 也就是再进行一遍等价变化回去就可以得到答案了

当然如果你一下判断边界比较迷糊的话我这有一份我自己写的憨批代码可以看看

// 数学公式要变形
// 莫急莫急先读题
#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x&(-x))
#define endl "\n"
#define ios ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
#define LF(x)   fixed<<setprecision(x)// c++ 保留小数
typedef long long LL;
typedef pair<int,int> PII;
typedef unsigned long long ULL;
const int N=1000010,M=1010,F=2*N,INF=0x3f3f3f3f,pp=133331;
const double pai=acos(-1.0);// pai
map<int,int> q;
LL t,n,m,x;

void solve()
{
    cin>>m>>x;
    LL ans=m/x+1,ans1=m/x;
    LL l=0,r=1e9+1;
    while(l<r){
        int mid=l+r+1>>1;
        if(ans1*mid>m) r=mid-1;
        else l=mid;
    }
    int y=m/ans+1;
    cout<<l-y+1<<endl;
        return ;
}

int main ()
{
    ios// 不能有printf puts scanf
    cin>>t;
    while(t--)
    solve();
    return 0;
}

D题扩展欧几里得加上性质判断

 由此我们可以知道如果对于

ax+by=c  c如果不是gcd(a,b)的倍数的话明显无解

扩展欧几里得的板子 

LL exgcd(LL a,LL b,LL &x,LL &y)
{
    if(!b)
    {
        x=1,y=0;
        return a;
    }
    LL d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}

然后这个是啥呢这个是满足条件的一组解

 cin>>a>>b>>n>>l>>r;
    LL ans=gcd(a,b),res=lcm(a,b);
    if(n%ans){
        cout<<"NO"<<endl;
        return ;
    }
    LL x,y;
    LL tt=res/a;
    exgcd(a,b,x,y);
    x*=n/ans,y*=n/ans;

注意是一组解

如果此时已经在范围那是好的

  if(x>=l&&x<=r){
        cout<<"YES"<<endl;
        return ;
    }

由此我们可以得出核心  就是用一个特解 解出满足条件的解

回归题意

b虽然可以左右走但是(b开局右走同理a不会超出范围(题意))

也就是说如果有解必然是

a*x+b*y=c;

那么我们求出一组特解之后呢?

也就是说我们如何让a的系数变到[l,r]的范围呢

我们要想如果要变化a的系数同时b也可以满足系数变化使得答案有解那么所移动的步数必然是

h, h=`lcm(a,b)/a 不然不会满足b的系数

这里再稍作解释

由于我们已经找到了一组解

如果说 要对a的系数变化  那么他变化的值一定来自于b的系数

也就是要维持有解的话

x*a变化的值也一定是 b的倍数

那么最小就是lcm(a,b);

对应到a的系数变化上就是lcm(a,b)/a

由此这个题结果得出

 如果解出的x<l

要让x到  [l,r] 第一个大于l的解

那么就是这个步骤  最后判断跳了之后是否小于r是的话就是有解 不然没解

if(x<l)
    {
        
      if((l-x)%tt==0)
      {
          cout<<"YES"<<endl;
          return ;
      }
    
        LL ll=(l-x)/tt*tt+tt+x;
        if(ll<=r)
        {
            cout<<"YES"<<endl;
            return ;
        }
    }

如果大于r同理 这里不在赘述

最后就是AC代码了

有点丑陋不过相信你肯定可以理解嘻嘻

// 数学公式要变形
// 莫急莫急先读题
#include <bits/stdc++.h>
using namespace std;
#define lowbit(x) (x&(-x))
#define endl "\n"
#define ios ios::sync_with_stdio(0); cin.tie(0),cout.tie(0);
#define LF(x)   fixed<<setprecision(x)// c++ 保留小数
typedef long long LL;
typedef pair<int,int> PII;
typedef unsigned long long ULL;
const int N=1000010,M=1010,F=2*N,INF=0x3f3f3f3f,pp=133331;
const double pai=acos(-1.0);// pai
map<int,int> q;
LL t,n,m;
LL gcd(LL a,LL b)
{
    return b?gcd(b,a%b):a;
}

LL exgcd(LL a,LL b,LL &x,LL &y)
{
    if(!b)
    {
        x=1,y=0;
        return a;
    }
    LL d=exgcd(b,a%b,y,x);
    y-=a/b*x;
    return d;
}
LL lcm(LL a,LL b)
{
    return a/gcd(a,b)*b;
}
LL a,b,l,r;
void solve()
{
    cin>>a>>b>>n>>l>>r;
    LL ans=gcd(a,b),res=lcm(a,b);
    if(n%ans){
        cout<<"NO"<<endl;
        return ;
    }
    LL x,y;
    LL tt=res/a;
    exgcd(a,b,x,y);
    x*=n/ans,y*=n/ans;
    
    if(x>=l&&x<=r){
        cout<<"YES"<<endl;
        return ;
    }
    if(x<l)
    {
        
      if((l-x)%tt==0)
      {
          cout<<"YES"<<endl;
          return ;
      }
    
        LL ll=(l-x)/tt*tt+tt+x;
        if(ll<=r)
        {
            cout<<"YES"<<endl;
            return ;
        }
    }
    if(x>r)
    {
        
       if((x-r)%tt==0)
      {
          cout<<"YES"<<endl;
          return ;
      }
      LL rr=x-(x-r)/tt*tt-tt;
        if(l<=rr)
        {
            cout<<"YES"<<endl;
            return ;
        }
    }
    cout<<"NO"<<endl;
        return ;
}

int main ()
{
    ios// 不能有printf puts scanf
    cin>>t;
    while(t--)
    solve();
    return 0;
}

 最后的题太难了不会,感觉还可以就点点赞吧,如有问题欢迎读者指正,一起加油

  • 16
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值