Codeforces Round #467 (Div. 2)T2题解

原题链接
http://codeforces.com/contest/937/problem/B
题目大意
给定两个数p和y,从2-p所有位置都有障碍,且这些障碍可以占领2-y中所有其的倍数
如p=3,y=6
2,3,一开始被占领
2的倍数4,6,被占领
3的倍数6,被占领
问在2-y中最大的未被占领的数是多少。如果全都被占领了,输出-1

题面
B. Vile Grasshoppers
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
The weather is fine today and hence it’s high time to climb the nearby pine and enjoy the landscape.

The pine’s trunk includes several branches, located one above another and numbered from 2 to y. Some of them (more precise, from 2 to p) are occupied by tiny vile grasshoppers which you’re at war with. These grasshoppers are known for their awesome jumping skills: the grasshopper at branch x can jump to branches .

Keeping this in mind, you wisely decided to choose such a branch that none of the grasshoppers could interrupt you. At the same time you wanna settle as high as possible since the view from up there is simply breathtaking.

In other words, your goal is to find the highest branch that cannot be reached by any of the grasshoppers or report that it’s impossible.

Input
The only line contains two integers p and y (2 ≤ p ≤ y ≤ 109).

Output
Output the number of the highest suitable branch. If there are none, print -1 instead.

Examples
inputCopy
3 6
output
5
inputCopy
3 4
output
-1
Note
In the first sample case grasshopper from branch 2 reaches branches 2, 4 and 6 while branch 3 is initially settled by another grasshopper. Therefore the answer is 5.

It immediately follows that there are no valid branches in second sample case.

赛时思路1:
硬判断,两重循环,一重外层从y到p(不含p)
一重内层从2-p
如果不能被整除就输出并结束程序
期望:通过预测试点;实际:第五个点超时
赛时思路2:
还是硬判断,不过进行一些小小的剪枝
剪枝1:任何一个合数都是若干个质数的乘积,所以合数就无需进行判断了,因为他们的质因子已经将其所有的倍数占领了
例子:p=4,y=8
当p=4时,其倍数4,8,皆以被其质因子2所占领,故减去这些合数
剪枝2:在外层的y-p循环中,如果当前数是一个质数,那么就无需进行内部的2-p判断直接输出,因为质数的因子只有1和他本身,所以这个质数不可能被2-p中的任何一个占领

代码

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
ll p,y;//定义p,y
bool prime(ll n) {//质数判断函数
    if(n<2)return 0;//这句在本程序中无实际作用,不过判断质数确实是这样的
    ll k=sqrt(n);//先将n的平方根存储下来,减少计算量
    for(ll i=2; i<=k; i++)
        if(n%i==0)return 0;//不是质数
    return 1;//是质数
}
int main() {
    ios::sync_with_stdio(false);//关闭同步,据说可以增加效率
    cin>>p>>y;//输入p,y
    for(ll i=y; i>p; i--) {//外层y-p循环
        bool flag=0;//是否符合要求
        if(prime(i)) {//剪枝2,如果是质数直接输出
            cout<<i<<endl;//输出
            return 0;//直接结束程序
        }
        for(ll j=2; j<=p; j++) {//内层2-p循环
            if(!prime(j))continue;//剪枝1,如果是合数就舍弃
            if(i%j==0) {//如果是2-p中某个数的倍数
                flag=1;//即不符合要求
                break;//退出内层循环
            }
        }
        if(!flag) {//要是符合要求
            cout<<i<<endl;//输出
            return 0;//直接结束程序
        }
    }
    cout<<-1<<endl;//运行到这里,说明无解
    return 0;//程序要休息了
}

赛后思考:本程序还可以进行优化,使用二分减少内层循环量,留给读者自行解决

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值