數學測試test20170304

【小Y的數學作業】(Homework.pas/c/cpp Time:1s Memory:256M)

【問題描述】

小Y是個很好學的孩子。(附註:Y=yang)
最近老師總是佈置給他(或者她)一些數學作業題,每道作業題就是求一個數X與數字A的最大公約數和X與數字B的最小公倍數。這天晚上11:00,大黃到小Y家去“玩”,不小心弄翻了小Y的咖啡,結果N道題的數字X都看不見了,但是數字A、數字B與小Y算出來的答案都還在。小Y很急,想問你對於每一道數學作業題,到底有多少種X滿足已經算出的答案。

【輸入】

輸入文件名爲homework.in。
第一行一個整數N,代表數學老師佈置的題目數量。
接下來N行,每行4個正整數A,A1,B,B1,代表Gcd(x,A)=A1,Lcm(x,B)=B1。

【輸出】

輸出文件名爲homework.out
對於每個數學題,若存在這樣的X,即輸出合法的X的個數,否則輸出0。

【輸入輸出樣例】

Homework.in
2
41 1 96 288
95 1 37 1776

Homework.out

6
2

【數據範圍】

對於50%的數據,保證有1≤A,A1,B,B1≤10000且n≤100。
對於100%的數據,保證有1≤A,A1,B,B1≤2,000,000,000且n≤2000。

【題解】

原題:NOIP2009第二題 Hankson 的趣味題 (傳送門)

首先,如果B1無法整除A1,那麼顯然是無解的。
然後,對於某一個質因數P來說,假設A包含p的最高次冪爲a,A1爲b,B爲c,B1爲d,然後X包含p的最高次冪爲x。
那麼x必須滿足如下條件:Min(x,a)=b;Max(c,x)=d;
這個是最大公約數和最小公倍數的基本性質。
通過這兩個條件,我們可以算出x的取值範圍。因爲不同質因數之間是互不影響的,所以就直接乘起來即可。
對於109 數分解質因數可以先把1到100000之間的質數篩出來,然後枚舉1到100000以內的質數,如果這樣之後還有剩餘的部分那麼就是最後那個剩下的質數了。

【代碼】

#include <cstdio>

int a0,a1,b0,b1,t;

inline int gcd(int x,int y){
    int i,j;
    if(x==0) return y;
    if(y==0) return x;
    for(i=0;(x&1)==0;i++) x>>=1;
    for(j=0;(y&1)==0;j++) y>>=1;
    if(j<i) i=j;
    while(1) {
        if(x<y) x^=y,y^=x,x^=y;
        if((x-=y)==0) return y<<i;
        while((x&1)==0) x>>=1;
    }
}

bool judge(int x) {
    return !(x%a1)&&1==gcd(x/a1,a0/a1)&&1==gcd(b1/b0,b1/x);
}

int main(){
    scanf("%d",&t);
    while(t--) {
        scanf("%d%d%d%d",&a0,&a1,&b0,&b1);
        int p=a0/a1;
        int ans=0;
        for(int k=1;k*k<=b1;k++) {
            if(!(b1%k)) {
                ans+=judge(k);
                if(k*k!=b1) 
                    ans+=judge(b1/k);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

【小Y的智力遊戲】(Game.pas/c/cpp Time:1s Memory:256M)

【問題描述】

小Y最近迷上了一款智力遊戲。(當然小Y還是很好學的)
這款智力遊戲就是讓你從1到N這N個數中,選取若干個不相等的正整數,使得它們的乘積爲一個完全平方數,同時,這個乘積也將成爲你的得分。
他(或她,以後這個括號就省略了)想知道最大得分對1000000007的模值。

【輸入】

輸入文件名game.in
一行一個正整數N,代表數字的個數。

【輸出】

輸出文件名game.out
一行一個正整數,代表最大得分對1000000007的模值。

【輸入輸出樣例】

Game.in Game.out
3 1

【數據範圍】

對於30%的數據,保證有n≤50。
對於60%的數據,保證有n≤1000。
對於70%的數據,保證有n≤10000。
對於80%的數據,保證有n≤100000。
對於90%的數據,保證有n≤1000000。
對於100%的數據,保證有n≤3000000。
【題解】

將 n! 唯一分解,然後將指數爲奇數的質因子的指數減去一,得到的唯一分解式就是答案

【代碼】

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long LL;
const int mod = 1000000007;
const int size = 3000010;
LL n,ans=1,tmp;
LL prime[size],cl[size],fir[size];
bool no_prime[size];

void fenjie(int x) {
    if(x==1) 
        return ;
    LL ret = fir[x];
    while(x%prime[ret]==0) {
        x/=prime[ret];
        cl[ret]++;
    }
    fenjie(x);
}

LL powermod(LL x,LL y,LL p) {
    if(y==0) 
        return 1;
    if(y==1) 
        return x%p;
    LL ret = powermod(x,y/2,p);
    ret = ret*ret%p;
    if(y&1)
        ret = ret*(x%p)%p;
    return ret;
}

int main() {
    freopen("game.in","r",stdin);
    freopen("game.out","w",stdout);
    scanf("%lld",&n);
    for(LL i=2;i<=n;i++) {
        if(!no_prime[i]) {
            prime[++tmp]=i;
            fir[i]=tmp;
        }
        for(LL j=1;prime[j]*i<=n;j++) {
            fir[prime[j]*i]=j;
            no_prime[prime[j]*i]=true;
            if(i%prime[j]==0)
                break;
        }
    }
    for(LL i=2;i<=n;i++) 
        fenjie(i);
    for(LL i=1;i<=tmp;i++) {
        if(cl[i]&1) 
            ans = ans*powermod(prime[i],cl[i]-1,mod)%mod;
        else 
            ans = ans*powermod(prime[i],cl[i],mod)%mod;
    }
    printf("%lld\n",ans);
    return 0;
}

【小Y的絕對戰爭】(War.pas/c/cpp Time:1s Memory:256M)

【問題描述】

小Y與大黃爆發了一場絕對要勝利的戰爭。(原因是大黃生活作風問題)
小Y現在擁有N個城池,每個城池都有一個強大值Wi。現在沒有一條通路連接任意兩個城池(通路是雙向的)。現在小Y想順次修建若干條通路,使得每修建一條通路都連接了兩個原本不連通的城池(聯通的定義是兩個城池之間存在一條由通路構成的路徑)。每修建一條通路IJ,那麼安全值就會增加Gcd(Wi,Wj)。爲了確保這場戰爭的勝利,小Y想知道,可能的最大安全值是多少(囧)。

【輸入】

輸入文件名爲war.in。
第一行一個正整數N,代表城池的個數。
接下來N行,每行一個正整數,代表這個城市的強大值。

【輸出】

輸出文件名爲war.out。
一行一個整數,代表最大的安全值。

【輸入輸出樣例】

War.in
4
1
2
3
4

War.out

4

【數據範圍】

對於30%的數據,保證有n≤1000。
對於100%的數據,保證有n≤1000000, 任意W小於等於1000000。
【題解】

這是顯然是求一顆最大生成樹。首先我們可以想到一個Kruskal的解法。也就是N^2LogN的。但是,很明顯因爲權值在1到1000000所以不同權值也最多隻有1000000,也就是說,可以直接從大到小枚舉權值,將點合併。對於一個權值I,可以取的所有點就是I的權值的倍數。這樣,時間複雜度就降低爲O(NlnN)

考試時我是直接O(n2) 出解

【代碼】

暫無

發佈了39 篇原創文章 · 獲贊 7 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章