1. 程式人生 > >NOIP複習模擬賽day1

NOIP複習模擬賽day1

首先先bb一下day1的題目名字怎麼都這麼鬼才......

1.兩情
(sweethearts.pas/c/cpp)

 

【問題描述】小 W 將要去和小 K 約會啦!但聰(ao)明(jiao)的小 K 並不想讓小 W 那麼容易知道他們的約會地點。於是小 W 收到了一條資訊:“給定兩個數的和 n,請你求出這兩個數的最小公倍數的可能值的最大值,作為交換,如果你給出了正確答案,我將會把你和小 K的約會地點告訴你。”眾所周知,小 W 是個數學弱渣,他只好求助數學巨佬小 H,但小 H 並不屑於做這種簡單題,於是幫助小 W 的任務就交給你啦!

【輸入】輸入檔案的第一行一個整數 T 表示資料組數。接下來 T 行每行一個整數 n ,表示給定的兩個數的和 n。

【輸出】共 T 行,每行一個整數表示和為 n 的兩個數的最小公倍數的可能值的最大值。

【輸入樣例】3

      2

      3

      4

【輸出樣例】1

      2

      3

【資料範圍】30%的資料滿足 T<=10,n<=1000 

      100% 的資料滿足 T<=10000 ,n<=109

 

官方題解:

  演算法描述

  100%
  若n為奇數,則a和b相差 1 最優
  若n為偶數,令m = n/2,若m - 1和m + 1均為奇數,則a = m - 1, b = m + 1
  否則a = m - 2, b = m + 2

  時間複雜度O(1)

  考察內容 特判,分類討論
  難度:簡單

   (是不是感覺題解沒什麼用,鬼才能想出來

 

自己bb的題解:

  其實,按照題目說的,要求max{lcm(x,y)}並且x+y=n。

  那麼可以有: y=n-x;

  並且lcm(x,y)=lcm(x,n-x);

  根據一個玄學的定理:lcm(x,y)=x*y/gcd(x,y)=x*(n-x)/gcd(x,n-x);

  也就是說當x*(n-x)越大,gcd(x,n-x)越小時,lcm(x,y)越大;

  還有一個初中的定理:那就是當週長相同時,正方形的面積越大;

  那麼根據這個定理,我們就可以知道,當x跟y相差的值越小x*y越大;

  另外一個,當x,y互質的時候gcd(x,y)=1最小;(互質是啥意思呢???就是x,y的公約數只有一個1。是不是很luozhi

  OK,那麼我們剛開始可以令x=y=n/2;

  然後x不斷的減1,y不斷的加1,在這個過程中我們要不斷的求gcd(x,y),看它是否為1,如果它為1,我們就退出迴圈,最後max{lcm(x,y)}=x*y;

  最後一定要記得開long long

    一定要記得開long long

    一定要記得開long long

 

  好了,上程式碼......

  

 1 //NOIPRP++
 2 #include<bits/stdc++.h>
 3 #define Re register int
 4 #define LL long long 
 5 using namespace std;
 6 LL T,x,l,r,Mid; 
 7 inline void read(LL &x){
 8     x=0; char c=getchar(); bool p=1;
 9     for (;'0'>c||c>'9';c=getchar()) if (c=='-') p=0;
10     for (;'0'<=c&&c<='9';c=getchar()) x=(x<<1)+(x<<3)+(c^48);
11     p?:x=-x;
12 }
13 int main(){
14     Re i,j;
15     read(T);
16     while (T--){
17         read(x);
18         l=x>>1;r=x-l; 
19         while (l<=r){
20             if (__gcd(l,r)==1){//C++自帶函式gcd......
21                 printf("%lld\n",l*r);
22                 break;
23             }
24             l--;r++;
25         }
26     }
27     return 0;
28 }
29 //NOIPRP++
View Code