码迷,mamicode.com
首页 > 其他好文 > 详细

测试 1

时间:2017-11-05 10:19:43      阅读:135      评论:0      收藏:0      [点我收藏+]

标签:16px   构造   limit   namespace   并查集   使用   onclick   ber   hellip   

立方数(cubic)

Time Limit:1000ms   Memory Limit:128MB

 

题目描述

LYK定义了一个数叫“立方数”,若一个数可以被写作是一个正整数的3次方,则这个数就是立方数,例如1,8,27就是最小的3个立方数。

现在给定一个数P,LYK想要知道这个数是不是立方数。

当然你有可能随机输出一些莫名其妙的东西来骗分,因此LYK有T次询问~

 

输入格式(cubic.in)

    第一行一个数T,表示有T组数据。

    接下来T行,每行一个数P。

 

输出格式(cubic.out)

输出T行,对于每个数如果是立方数,输出“YES”,否则输出“NO”。

 

输入样例

3

8

27

28

 

输出样例

YES

YES

NO

 

数据范围

对于30%的数据p<=100。

对于60%的数据p<=10^6。

对于100%的数据p<=10^18,T<=100。

思路:暴力

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
int T;
long long n;
int main(){
    freopen("cubic.in","r",stdin);
    freopen("cubic.out","w",stdout);
    scanf("%d",&T);
    while(T--){
        bool flag=0;
        scanf("%I64d",&n);
        for(long long i=1;i<=1000000;i++)
            if(i*i*i==n){
                cout<<"YES"<<endl;
                flag=1;break;
            }
        if(!flag)    cout<<"NO"<<endl;
    }
}
/*
3
8
27
28
*/

 

 

 

 

立方数2(cubicp)

Time Limit:1000ms   Memory Limit:128MB

 

题目描述

LYK定义了一个数叫“立方数”,若一个数可以被写作是一个正整数的3次方,则这个数就是立方数,例如1,8,27就是最小的3个立方数。

LYK还定义了一个数叫“立方差数”,若一个数可以被写作是两个立方数的差,则这个数就是“立方差数”,例如7(8-1),26(27-1),19(27-8)都是立方差数。

现在给定一个数P,LYK想要知道这个数是不是立方差数。

当然你有可能随机输出一些莫名其妙的东西,因此LYK有T次询问~

这个问题可能太难了…… 因此LYK规定P是个质数!

 

输入格式(cubicp.in)

    第一行一个数T,表示有T组数据。

    接下来T行,每行一个数P。

 

输出格式(cubicp.out)

输出T行,对于每个数如果是立方差数,输出“YES”,否则输出“NO”。

 

输入样例

5

2

3

5

7

11

 

输出样例

NO

NO

NO

YES

NO

 

 

数据范围

对于30%的数据p<=100。

对于60%的数据p<=10^6。

对于100%的数据p<=10^12,T<=100。

思路:

技术分享
#include<set>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
set<int>se;
int T;
long long n[1100],maxn;
int main(){
    freopen("cubicp.in","r",stdin);
    freopen("cubicp.out","w",stdout);
    scanf("%d",&T);
    for(int i=1;i<=T;i++){
        scanf("%I64d",&n[i]);
        maxn=max(maxn,n[i]);
    }
    if(maxn<=100){
        for(long long int i=1;i<=7;i++)
            for(long long int j=i+1;j<=7;j++){
                long long x=j*j*j-i*i*i;
                if(se.find(x)==se.end())    se.insert(x);
            }
    }
    else if(maxn<=1000000){
        for(long long int i=1;i<=579;i++)
            for(long long int j=i+1;j<=579;j++){
                long long x=j*j*j-i*i*i;
                if(se.find(x)==se.end())    se.insert(x);
            }
    }
    else if(maxn<=2000000){
        for(long long int i=1;i<=868;i++)
            for(long long int j=i+1;j<=868;j++){
                long long x=j*j*j-i*i*i;
                if(se.find(x)==se.end())    se.insert(x);
            }
    }
    else if(maxn<=3000000){
        for(long long int i=1;i<=1001;i++)
            for(long long int j=i+1;j<=1001;j++){
                long long x=j*j*j-i*i*i;
                if(se.find(x)==se.end())    se.insert(x);
            }
    }
    else if(maxn<=100000000){
        for(long long int i=1;i<=5779;i++)
            for(long long int j=i+1;j<=5779;j++){
                long long x=j*j*j-i*i*i;
                if(se.find(x)==se.end())    se.insert(x);
            }
    }
    else{
        for(long long int i=1;i<=10000;i++)
            for(long long int j=i+1;j<=10000;j++){
                long long x=j*j*j-i*i*i;
                if(se.find(x)==se.end())    se.insert(x);
            }
    }
    for(int i=1;i<=T;i++){
        if(se.find(n[i])!=se.end())    cout<<"YES"<<endl;
        else cout<<"NO"<<endl;
    }
}
/*
5
2
3
5
7
11
*/
60分暴力

由立方差公式得:技术分享=q

q是质数。

所以(a-b)=1.

a=(b+1)

所以(a^2+ab+b^2)=(b+1)^2+(b+1)*b+b^2=q;

因为q[1,1000000000000]

所以b∈[1,1000000];

暴力枚举b即可。

#include<cstdio>
#include<cstring>
#include <iostream>
#include<algorithm>
using namespace std;
int t,flag;
long long p;
int main(){
    freopen("cubicp.in","r",stdin);
    freopen("cubicp.out","w",stdout);    
    scanf("%d",&t);
    while(t--){
        flag=0;
        scanf("%I64d",&p);
        for(int i=1;i<=1e6+10;i++){
            if(3ll*i*i+3*i+1==p){
                flag=1;
                break;
            }
            if (3ll*i*i+3*i+1>p) break;
        }
        if(flag)    printf("YES\n");
        else    printf("NO\n");
    }
}

 

 

猜数字(number)

Time Limit:1000ms   Memory Limit:128MB

 

题目描述

    LYK在玩猜数字游戏。

    总共有n个互不相同的正整数,LYK每次猜一段区间的最小值。形如[li,ri]这段区间的数字的最小值一定等于xi。

    我们总能构造出一种方案使得LYK满意。直到…… LYK自己猜的就是矛盾的!

    例如LYK猜[1,3]的最小值是2,[1,4]的最小值是3,这显然就是矛盾的。

    你需要告诉LYK,它第几次猜数字开始就已经矛盾了。

 

输入格式(number.in)

    第一行两个数n和T,表示有n个数字,LYK猜了T次。
    接下来T行,每行三个数分别表示li,ri和xi。

 

输出格式(number.out)

输出一个数表示第几次开始出现矛盾,如果一直没出现矛盾输出T+1。

 

输入样例

20 4

1 10 7

5 19 7

3 12 8

1 20 1

 

输出样例

3

 

数据范围

对于50%的数据n<=8,T<=10。

对于80%的数据n<=1000,T<=1000。

对于100%的数据1<=n,T<=1000000,1<=li<=ri<=n,1<=xi<=n(但并不保证一开始的所有数都是1~n的)。

 

Hint

建议使用读入优化

inline int read()

{

       int x = 0, f = 1;

       char ch = getchar();

       for(; !isdigit(ch); ch = getchar()) if(ch == ‘-‘) f = -1;

       for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - ‘0‘;

       return x * f;

}

思路:

第几次出现矛盾
1.二分,1~mid中出现矛盾 答案一定在1~mid中
1~mid可行 1~mid-1也可行
1~mid不可行 1~mid+1不可行
2.枚举,每次输入判断是否可行

 

左/右端点进行排序 ×
xi排序 √
从大到小

 

[l,r]之前被大于x的更大的区间覆盖过 不可行!!
[1,10] 7&&[5,19] 7-->[5,10] 7
xi相同的进行区间交

 

从大到小枚举xi 判断比xi大的区间的并是否完全覆盖这个区间

 

exp:1~5-->9 3~7-->8
2~6-->6 矛盾!!

 

线段树!!

 

并查集维护

 

O(nlogn*αn)
重点:check

 

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define MAXN 1000011
using namespace std;
int n,q,ans;
int l,r,mid;
int fa[MAXN];
struct nond{
    int x,y,z;
}v[MAXN],tmp[MAXN];
int cmp(nond a,nond b){
    return a.z>b.z;
}
int find(int x){
    if(fa[x]==x)    return fa[x];
    else return fa[x]=find(fa[x]);
}
bool judge(int k){
    int lmin,rmin,lmax,rmax;
    for(int i=1;i<=n+1;i++)    fa[i]=i;
    for(int i=1;i<=k;i++)    tmp[i]=v[i];
    sort(tmp+1,tmp+1+k,cmp); 
    lmin=lmax=tmp[1].x;
    rmin=rmax=tmp[1].y;
    for(int i=2;i<=k;i++){
        if(tmp[i].z<tmp[i-1].z){
            if(find(lmax)>rmin)    return true;
            for(int j=find(lmin);j<=rmax;j++)
                fa[find(j)]=find(rmax+1);
            lmin=lmax=tmp[i].x;
            rmin=rmax=tmp[i].y;
        }
        else{
            lmin=min(lmin,tmp[i].x);
            lmax=max(lmax,tmp[i].x);
            rmin=min(rmin,tmp[i].y);
            rmax=max(rmax,tmp[i].y);
            if(lmax>rmin)    return true;
        }
    }
    if(find(lmax)>rmin)    return true;
    return false;
}
int main(){
    freopen("number.in","r",stdin);
    freopen("number.out","w",stdout);
    scanf("%d%d",&n,&q);
    for(int i=1;i<=q;i++)
        scanf("%d%d%d",&v[i].x,&v[i].y,&v[i].z);
    l=1;r=q;ans=q+1;
    while(l<=r){
        mid=(l+r)/2;
        if(judge(mid))    ans=mid,r=mid-1;
        else l=mid+1;
    }
    cout<<ans;
}
/*
20 4
1 10 7
5 19 7
3 12 8
1 20 1
*/

 

测试 1

标签:16px   构造   limit   namespace   并查集   使用   onclick   ber   hellip   

原文地址:http://www.cnblogs.com/cangT-Tlan/p/7746217.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!