题干:
因为现在的新生太强了,都学会了“dp”,所以就有了这样一个“dp”题,双11时Gugugu有(x,x+1,x+2....y-1,y)元的抵用券无数张,但是Gugugu有强迫症所以他希望他使用抵扣券正好能够抵扣k元,这样他就能安心的买下这件商品,但是他却不会计算所以希望你们告诉他能不能一种方法使抵用券正好抵扣k元。
输入描述:
第一行输入t代表有t组数据,第二行开始每行三个数k,x,y代表需要抵扣k元,x,y代表拥有抵用券的最小面值和最大面值。(1<=t<=200)(1<=k,x,y<109)(x<=y)
输出描述:
输出"Y"代表示能正好抵扣,输出"N"代表不能正好抵扣
示例1
输入
2
7 2 4
6 4 5
输出
Y
N
解题报告:
AC代码:(一个AC代码,但是不加那些剪枝会T)
#include<bits/stdc++.h>
using namespace std;
long long k,x,y;
int main(){
int T ;
scanf("%d",&T);
while(T--){
scanf("%lld%lld%lld",&k,&x,&y);
if(k<x) printf("N\n");
else if(k>=x&&k<=y) printf("Y\n");
else{
int flag=0;
for(int i=2;i<=10000000;i++){
if(x*i<=k&&k<=y*i){
printf("Y\n");
flag=1;
break;
}
}
if(!flag)printf("N\n");
}
}
}
AC代码2:(这样也可以500ms左右AC,其实可能是因为数据水了,我把枚举上界改成1e4也AC了,等等好像1e3也AC了,确定是数据水了)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define ll long long
#define pb push_back
#define pm make_pair
#define fi first
#define se second
using namespace std;
const int MAX = 2e5 + 5;
ll k,x,y;
int main()
{
int t;
cin>>t;
while(t--) {
scanf("%lld%lld%lld",&k,&x,&y);
int ff=0;
for(ll i = 1; i<=(ll)1e7; i++) {
if(i*x <=k && i*y >=k) {
ff=1;puts("Y");break;
}
}
if(ff==0) puts("N");
}
return 0 ;
}
正解:
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
typedef pair<int,int> PI;
const int maxn = 1e5+5;
const ULL mod = 1e9+7;
const LL inf = 1e18;
int main()
{
int T; scanf( "%d", &T );
while( T-- )
{
int k,x,y; scanf( "%d%d%d", &k, &x, &y );
if( k<x ) printf( "N\n" );
else if( k>=x&&k<=y||k%x==0 ) printf( "Y\n" );
else
{
int pp = k/x;
int p = k%x;
if( p%pp==0 ) p /= pp;
else p = p/pp+1;
if( p<=y-x ) printf( "Y\n" );
else printf( "N\n" );
}
}
return 0;
}