1. 程式人生 > >清北考前刷題day1早安

清北考前刷題day1早安

rmi clu 輸入格式 是個 一個數 分答 個數 getch 出現

立方數(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<iostream>
#include<cstdio>
#include<cstring>

#define ll long long
#define K 1000001

using namespace std;
ll T,n,x,ans,cnt;

inline ll read()
{
    ll x
=0,f=1;char c=getchar(); while(c>9||c<0){if(c==-)f=-1;c=getchar();} while(c>=0&&c<=9){x=x*10+c-0;c=getchar();} return x*f; } int main() { // freopen("cubic.in","r",stdin); // freopen("cubic.out","w",stdout); T=read(); while(T--) { x
=read();bool flag=0; for(ll i=1;i<=K;i++) { if(x==i*i*i) { printf("YES\n"); flag=1;break; } } if(!flag){printf("NO\n");} } return 0; }

立方數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。

/*X^3-Y^3=(x-y)(x^2+xy+y^2)
p是素數 ->(x-y)=1; y=x-1
x^2+x(x-1)+(x-1)^2=p

若p不是素數可以枚舉p的因數d,就是枚舉(x-y)。把(x-1)改為x-d。
*/
#include <iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#include<set>
#include<string>
using namespace std;
int main()
{
    freopen("cubicp.in","r",stdin);
    freopen("cubicp.out","w",stdout);
    int t,flag;
    scanf("%d",&t);
    long long p;
    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");
    }
    return 0;
}

猜數字(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;

}

/*
二分答案 出現矛盾的時間
判定性
按xi從大到小排序後,在[l,r]內,若之前以被覆蓋過,則矛盾。
要求互不相同,若[1,10]->7 [5,19]->7 則說明[5,10]->7,[1,4]和[11,19]最小值大於7;
所以可以合並xi相同的區間,區間交。
從大到小枚舉xi判斷是否有大於xi的區間並覆蓋了這個區間。

可用線段樹
查詢:區間最小值是否為0
修改:區間改為1,不是修改區間的交,而是最小值為xi的區間並。
O(nlgn^2n);

正解並查集
f[i]表示以i開始最近的沒被覆蓋過的位置是哪個。
若[1,6]->7 則f[1]...f[6]=7

for(int i=f[1];i<=r;i=f[i+1])

f[l]是否>r

*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

#define N 1000007

using namespace std;
int n,q,ans;
int f[N];//f[i]表示以i開始最近的沒被覆蓋過的位置是哪個。
struct node{
    int x,y,z;
}p[N],t[N];

inline int read()
{
    int x=0,f=1;char c=getchar();
    while(c>9||c<0){if(c==-)f=-1;c=getchar();}
    while(c>=0&&c<=9){x=x*10+c-0;c=getchar();}
    return x*f;
}

bool cmp(node x,node y){return x.z>y.z;}
inline int find(int x){return x==f[x]?x:f[x]=find(f[x]);}

inline bool check(int k)
{
    int x,y,lmin,lmax,rmin,rmax;
    for(int i=1;i<=n;i++)f[i]=i;
    for(int i=1;i<=k;i++)t[i]=p[i];
    sort(t+1,t+k+1,cmp);
    lmin=lmax=t[1].x;rmin=rmax=t[1].y;
    for(int i=2;i<=k;i++)
    {
        if(t[i].z<t[i-1].z)
        {
            if(find(lmax)>rmin) return 1;
            for(int j=find(lmin);j<=rmax;j++)
              f[find(j)]=find(rmax+1);
            lmin=lmax=t[i].x;
            rmin=rmax=t[i].y;
        }
        else
        {
            lmin=min(lmin,t[i].x);
            lmax=max(lmax,t[i].x);
            rmin=min(rmin,t[i].y);
            rmax=max(rmax,t[i].y);
            if(lmax>rmin) return 1;
        }
    }
    if(find(lmax)>rmin) return 1;
    return 0;
}

int main()
{
    int x,y,mid;
    n=read();q=read();
    for(int i=1;i<=q;i++)
      p[i].x=read(),p[i].y=read(),p[i].z=read();
    x=1,y=q;ans=q+1;
    while(x<=y)
    {
        mid=x+y>>1;
        if(check(mid)) ans=mid,y=mid-1;
        else x=mid+1;
    }
    printf("%d\n",ans);
    return 0;
}

清北考前刷題day1早安