青蛙与兔子的约会

链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
 

每当晚上时,青蛙都会出来活动,白天休息。白天时,兔子就会出来活动,晚上休息。

青蛙一次可以跳 aaa 米,兔子一次可以跳 bbb 米,已知青蛙在坐标 000 的位置,兔子在坐标 nnn 的位置。

现在青蛙与兔子在明天白天有个约会,但是青蛙不想等太久兔子,他决定在今天夜晚时就开始行动。

但是青蛙又怕累,所以晚上时青蛙只会向兔子的方向跳 [L,R][L,R][L,R] 次。

问青蛙能否与兔子约会?

输入共 T+1T+1T+1 行。

第一行一个整数表示 T (1≤T≤105)T\ (1≤T≤10^5)T (1≤T≤105)。

接下来 TTT 行,每行 555 个整数表示 a,b,n,L,R(1≤a,b,n,L,R≤109,L≤R)a,b,n,L,R (1≤a,b,n,L,R≤10^9,L ≤ R)a,b,n,L,R(1≤a,b,n,L,R≤109,L≤R)。

数据保证青蛙不会跳过nnn的位置,即 1≤La≤Ra≤n1≤ La≤ Ra ≤ n1≤La≤Ra≤n 。

输出共 TT 行,每行一个"YES" 或 "NO"(不包括双引号),表示青蛙和兔子能否约会。
输入输出
3
3 4 10 1 2
2 4 5 1 1
3 5 11 1 1
YES
NO
NO

这是一个典型的Exgcd(拓展欧几里得),求两元一次不定式方程ax+by=n的整数解

先求ax+by=n的解

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

这个板子求出的解是ax+by=gcd(a,b)的解,首先判断是否有整数解

如果n整除d,就有整数解,反之没有

然后求通解,上面x,y是求出来的特解

通解=特解+齐次解

ax+by=d的特解为(x,y)

ax+by=n的特解为(a*n/d,y*n/d)

齐次解 ax+by=0的解为(k*b/d,k*a/d),k属于Z

通解为(a*n/d+k*b/d,y*n/d+k*a/d),由题可知,y1=1,x1=a*n/d+k*b/d,判断与[l,r]是否有交集

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector> 
#define int long long
using namespace std;
const int N=1e6+10;
int exgcd(int a,int b,int &x,int &y)
{
    if(!b)
    {
        x=1,y=0;
        return a;
    }
    int d=exgcd(b,a%b,y,x);
    y-=(a/b*x);
    return d;
}
signed main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
	int t;
	cin>>t;
	while(t--)
	{
		int a,b,n,l,r,x,y;
		cin>>a>>b>>n>>l>>r;
		int d=exgcd(a,b,x,y);//ax+by=gcd(a,b)的解
		if(n%d!=0)
		{
			cout<<"NO\n";//没有整数解
		}
		else
		{
			int x0=x*n/d;//ax+by=n的特解 通解为x0+k*b
			b=b/d;
			int x1=(x0+b)%b;//最小特解
			x1+=l/b*b;//找接近l的解
			while(x1<l)找第一个大于l的解
			x1+=b;
			if(x1<=r)
			cout<<"YES\n";
			else
			cout<<"NO\n";
		}
	}
	return 0;
}

这么简单的题不能秒吗

 

Takahashi 有一个整数 xx。一开始 x = 0x=0。Takahashi 可以做如下操作若干次:

  • 选择一个整数 ii(1 \le i \le 91≤i≤9)。花 C_iCi​ 元将 xx 替换为 10x + i10x+i。

Takahashi 的预算有 NN 元。请求出在不超过预算的前提下,通过若干次操作得到的最终的 xx 的最大值。

输入输出
5
5 4 3 3 2 5 3 5 3
95
20
1 1 1 1 1 1 1 1 1
99999999999999999999
 

 这个题是在nyist的tt赛中发现的,思维题,代码简单,就是不太好想的感觉

首先,需要注意这个数组中的费用在满足条件的情况下,可以循环使用,不是只能用一次,是个贪心题。

思路:找到最小的花销,k/最小花销就是结果的最大长度,选取的数既要下标最大,还要满足位数不变,也就是说k不断变小,在位数没遍历完时,k不能为0

 

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e2+10;
int a[N];
signed main()
{
  ios::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n,mn=INT_MAX;
  cin>>n;
  for(int i=1;i<=9;i++)
  {
  	cin>>a[i];
  	mn=min(mn,a[i]);//找最小花销
  }
  int k=n/mn;//最长位数
  for(int i=1;i<=k;i++)
  {
  	for(int j=9;j>=1;j--)
  	{
	  	if(n-a[j]>=mn*(k-i))//判断位数不能少
	  	{
		  	n-=a[j];
		  	cout<<j;
		  	break;
		  }
	  }
  }
  return 0;
}

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值