CSP-J 2023 T3 一元二次方程

文章目錄

  • 題目
    • 題目背景
    • 題目描述
    • 輸入格式
    • 輸出格式
    • 樣例 #1
      • 樣例輸入 #1
      • 樣例輸出 #1
    • 提示
  • 題目傳送門
  • 題解
    • 思路
    • 總代碼
  • 提交結果
  • 尾聲

題目

題目背景

眾所周知,對一元二次方程 a x 2 + b x + c = 0 , ( a ≠ 0 ) ax ^ 2 + bx + c = 0, (a \neq 0) ax2+bx+c=0,(a=0),可以用以下方式求實數解:

  • 計算 Δ = b 2 ? 4 a c \Delta = b ^ 2 - 4ac Δ=b2?4ac,則:
    1. Δ < 0 \Delta < 0 Δ<0,則該一元二次方程無實數解。
    2. 否則 Δ ≥ 0 \Delta \geq 0 Δ0,此時該一元二次方程有兩個實數解 x 1 , 2 = ? b ± Δ 2 a x _ {1, 2} = \frac{-b \pm \sqrt \Delta}{2a} x1,2?=2a?b±Δ ??

例如:

  • x 2 + x + 1 = 0 x ^ 2 + x + 1 = 0 x2+x+1=0 無實數解,因為 Δ = 1 2 ? 4 × 1 × 1 = ? 3 < 0 \Delta = 1 ^ 2 - 4 \times 1 \times 1 = -3 < 0 Δ=12?4×1×1=?3<0
  • x 2 ? 2 x + 1 = 0 x ^ 2 - 2x + 1 = 0 x2?2x+1=0 有兩相等實數解 x 1 , 2 = 1 x _ {1, 2} = 1 x1,2?=1
  • x 2 ? 3 x + 2 = 0 x ^ 2 - 3x + 2 = 0 x2?3x+2=0 有兩互異實數解 x 1 = 1 , x 2 = 2 x _ 1 = 1, x _ 2 = 2 x1?=1,x2?=2

在題面描述中 a a a b b b 的最大公因數使用 gcd ? ( a , b ) \gcd(a, b) gcd(a,b) 表示。例如 12 12 12 18 18 18 的最大公因數是 6 6 6,即 gcd ? ( 12 , 18 ) = 6 \gcd(12, 18) = 6 gcd(12,18)=6

題目描述

現在給定一個一元二次方程的系數 a , b , c a, b, c a,b,c,其中 a , b , c a, b, c a,b,c 均為整數且 a ≠ 0 a \neq 0 a=0。你需要判斷一元二次方程 a x 2 + b x + c = 0 a x ^ 2 + bx + c = 0 ax2+bx+c=0 是否有實數解,并按要求的格式輸出。

在本題中輸出有理數 v v v 時須遵循以下規則:

  • 由有理數的定義,存在唯一的兩個整數 p p p q q q,滿足 q > 0 q > 0 q>0 gcd ? ( p , q ) = 1 \gcd(p, q) = 1 gcd(p,q)=1 v = p q v = \frac pq v=qp?

  • q = 1 q = 1 q=1則輸出 {p},否則輸出 {p}/{q},其中 {n} 代表整數 n n n 的值;

  • 例如:

    • v = ? 0.5 v = -0.5 v=?0.5 時, p p p q q q 的值分別為 ? 1 -1 ?1 2 2 2,則應輸出 -1/2
    • v = 0 v = 0 v=0 時, p p p q q q 的值分別為 0 0 0 1 1 1,則應輸出 0

對于方程的求解,分兩種情況討論:

  1. Δ = b 2 ? 4 a c < 0 \Delta = b ^ 2 - 4ac < 0 Δ=b2?4ac<0,則表明方程無實數解,此時你應當輸出 NO

  2. 否則 Δ ≥ 0 \Delta \geq 0 Δ0,此時方程有兩解(可能相等),記其中較大者為 x x x,則:

    1. x x x 為有理數,則按有理數的格式輸出 x x x

    2. 否則根據上文公式, x x x 可以被唯一表示為 x = q 1 + q 2 r x = q _ 1 + q _ 2 \sqrt r x=q1?+q2?r ? 的形式,其中:

      • q 1 , q 2 q _ 1, q _ 2 q1?,q2? 為有理數,且 q 2 > 0 q _ 2 > 0 q2?>0
      • r r r 為正整數且 r > 1 r > 1 r>1,且不存在正整數 d > 1 d > 1 d>1 使 d 2 ∣ r d ^ 2 \mid r d2r(即 r r r 不應是 d 2 d ^ 2 d2 的倍數);

    此時:

    1. q 1 ≠ 0 q _ 1 \neq 0 q1?=0,則按有理數的格式輸出 q 1 q _ 1 q1?,并再輸出一個加號 +
    2. 否則跳過這一步輸出;

    隨后:

    1. q 2 = 1 q _ 2 = 1 q2?=1,則輸出 sqrt({r})
    2. 否則若 q 2 q _ 2 q2? 為整數,則輸出 {q2}*sqrt({r})
    3. 否則若 q 3 = 1 q 2 q _ 3 = \frac 1{q _ 2} q3?=q2?1? 為整數,則輸出 sqrt({r})/{q3}
    4. 否則可以證明存在唯一整數 c , d c, d c,d 滿足 c , d > 1 , gcd ? ( c , d ) = 1 c, d > 1, \gcd(c, d) = 1 c,d>1,gcd(c,d)=1 q 2 = c d q _ 2 = \frac cd q2?=dc?,此時輸出 {c}*sqrt({r})/{d}

    上述表示中 {n} 代表整數 {n} 的值,詳見樣例。

    如果方程有實數解,則按要求的格式輸出兩個實數解中的較大者。否則若方程沒有實數解,則輸出 NO

輸入格式

輸入的第一行包含兩個正整數 T , M T, M T,M,分別表示方程數和系數的絕對值上限。

接下來 T T T 行,每行包含三個整數 a , b , c a, b, c a,b,c

輸出格式

輸出 T T T 行,每行包含一個字符串,表示對應詢問的答案,格式如題面所述。

每行輸出的字符串中間不應包含任何空格

樣例 #1

樣例輸入 #1

9 1000
1 -1 0
-1 -1 -1
1 -2 1
1 5 4
4 4 1
1 0 -432
1 -3 1
2 -4 1
1 7 1

樣例輸出 #1

1
NO
1
-1
-1/2
12*sqrt(3)
3/2+sqrt(5)/2
1+sqrt(2)/2
-7/2+3*sqrt(5)/2

提示

【樣例 #2】

見附件中的 uqe/uqe2.inuqe/uqe2.ans

【數據范圍】

對于所有數據有: 1 ≤ T ≤ 5000 1 \leq T \leq 5000 1T5000 1 ≤ M ≤ 1 0 3 1 \leq M \leq 10 ^ 3 1M103 ∣ a ∣ , ∣ b ∣ , ∣ c ∣ ≤ M |a|,|b|,|c| \leq M a,b,cM a ≠ 0 a \neq 0 a=0

測試點編號 M ≤ M \leq M特殊性質 A特殊性質 B特殊性質 C
1 1 1 1 1 1
2 2 2 20 20 20
3 3 3 1 0 3 10 ^ 3 103
4 4 4 1 0 3 10 ^ 3 103
5 5 5 1 0 3 10 ^ 3 103
6 6 6 1 0 3 10 ^ 3 103
7 , 8 7, 8 7,8 1 0 3 10 ^ 3 103
9 , 10 9, 10 9,10 1 0 3 10 ^ 3 103

其中:

  • 特殊性質 A:保證 b = 0 b = 0 b=0
  • 特殊性質 B:保證 c = 0 c = 0 c=0
  • 特殊性質 C:如果方程有解,那么方程的兩個解都是整數。

題目傳送門

洛谷 P9750 [CSP-J 2023] 一元二次方程

題解

思路

沒有任何算法,純粹的大模擬,細節還蠻多的

由于這道題有多測,所以用一個函數比較好,可以把 a , b , c a,b,c a,b,c 都傳進去,這就是主函數

int T, m;
int a, b, c;
int main() {scanf("%d%d", &T, &m);while(T-- && scanf("%d%d%d", &a, &b, &c))work(a, b, c);return 0;
}

函數里面首先是判斷無解,也就是 Δ < 0 \Delta<0 Δ<0,那我們就需要算出 Δ \Delta Δ,即 b 2 ? 4 a c b^2-4ac b2?4ac

int delta = b * b - 4 * a * c;void work(int a, int b, int c) {delta = b * b - 4 * a * c;if(delta < 0) {puts("NO");return;}
}

然后需要判斷 Δ \Delta Δ 是完全平方數,那么就可以直接算出 ? b + Δ 2 a \frac{-b+\sqrt\Delta}{2a} 2a?b+Δ ?? ? b ? Δ 2 a \frac{-b-\sqrt\Delta}{2a} 2a?b?Δ ?? 哪個大,然后如果能除開就直接輸出那個根,否則就輸出約分后的那個根

(那個 p r i n t d i v i s i o n ( p , q ) printdivision(p,q) printdivision(p,q) 函數是用來輸出 p / q p/q p/q 的,具體請參考注釋)

int delta;
double x1, x2;
int sq;void print_division(int p, int q) {if(!p) {											// 分子為 0,則輸出 0 putchar('0');return;}if(p * q < 0)										// 兩數異號,則輸出符號 putchar('-');if(p < 0)											// 將兩數都變成正數 p = -p;if(q < 0)q = -q;int g = __gcd(p, q);								// 約分 p /= g;q /= g;if(q == 1)											// 分母為 1,則輸出分子 printf("%d", p);else												// 否則輸出 “分子/分母” printf("%d/%d", p, q);
}void work(int a, int b, int c) {delta = b * b - 4 * a * c;if(delta < 0) {puts("NO");return;}sq = sqrt(delta);if(sq * sq == delta) {x1 = 1.0 * (-b + sq) / 2 * a;x2 = 1.0 * (-b - sq) / 2 * a;if(x1 > x2)print_division(-b + sq, 2 * a);elseprint_division(-b - sq, 2 * a);puts("");return;}
}

否則的話就需要按照 “ ? b / 2 a + Δ / 2 a -b/2a+\sqrt\Delta/2a ?b/2a+Δ ?/2a” 的格式輸出

首先如果 b ≠ 0 b\neq0 b=0,那么就說明 ? b / 2 a ≠ 0 -b/2a\neq0 ?b/2a=0,就可以輸出 “ ? b / 2 a + -b/2a+ ?b/2a+

為什么一定是 + + + ?因為如果是 ? b ? Δ 2 a \frac{-b-\sqrt\Delta}{2a} 2a?b?Δ ?? 更大,那就說明 2 a < 0 2a<0 2a<0,否則不可能 ? b ? Δ 2 a > ? b ? Δ 2 a \frac{-b-\sqrt\Delta}{2a}>\frac{-b-\sqrt\Delta}{2a} 2a?b?Δ ??>2a?b?Δ ??,所以一定是 + + +

最后就是輸出 Δ / 2 a \sqrt\Delta/2a Δ ?/2a 了,具體怎么做請參考代碼注釋

int delta;
double x1, x2;
int sq;void print_division(int p, int q) {if(!p) {											// 分子為 0,則輸出 0 putchar('0');return;}if(p * q < 0)										// 兩數異號,則輸出符號 putchar('-');if(p < 0)											// 將兩數都變成正數 p = -p;if(q < 0)q = -q;int g = __gcd(p, q);								// 約分 p /= g;q /= g;if(q == 1)											// 分母為 1,則輸出分子 printf("%d", p);else												// 否則輸出 “分子/分母” printf("%d/%d", p, q);
}void print_sqrt(int p, int q) {if(q < 0)											// 如果分母是負數,則將其變為正數,因為和前面的負號消沒了(上文說過了) q = -q;int u = 1;											// 根號前面的系數 for(int i = sqrt(p); i > 1; --i)					// 化簡 if(!(p % (i * i))) {p /= i * i;u *= i;break; }int g = __gcd(u, q);								// 約分 u /= g;q /= g;if(u > 1)											// 系數大于 1,則輸出 “系數*” printf("%d*", u);if(p > 1)											// 根號下的數大于 1,則輸出 “sqrt(根號下的數)” printf("sqrt(%d)", p);if(q > 1)											// 分母大于 1,則輸出 “/分母” printf("/%d", q);
}void work(int a, int b, int c) {delta = b * b - 4 * a * c;if(delta < 0) {puts("NO");return;}sq = sqrt(delta);if(sq * sq == delta) {x1 = 1.0 * (-b + sq) / 2 * a;x2 = 1.0 * (-b - sq) / 2 * a;if(x1 > x2)print_division(-b + sq, 2 * a);elseprint_division(-b - sq, 2 * a);puts("");return;}if(b) {print_division(-b, 2 * a);putchar('+');}print_sqrt(delta, 2 * a);puts("");
}

總代碼

#include <cstdio>
#include <algorithm>
#include <cmath>
using namespace std;int T, m;
int a, b, c;
int delta;
double x1, x2;
int sq;void print_division(int p, int q) {if(!p) {putchar('0');return;}if(p * q < 0)putchar('-');if(p < 0)p = -p;if(q < 0)q = -q;int g = __gcd(p, q);p /= g;q /= g;if(q == 1)printf("%d", p);elseprintf("%d/%d", p, q);
}void print_sqrt(int p, int q) {if(q < 0)q = -q;int u = 1;for(int i = sqrt(p); i > 1; --i)if(!(p % (i * i))) {p /= i * i;u *= i;break; }int g = __gcd(u, q);u /= g;q /= g;if(u > 1)printf("%d*", u);if(p > 1)printf("sqrt(%d)", p);if(q > 1)printf("/%d", q);
}void work(int a, int b, int c) {delta = b * b - 4 * a * c;if(delta < 0) {puts("NO");return;}sq = sqrt(delta);if(sq * sq == delta) {x1 = 1.0 * (-b + sq) / 2 * a;x2 = 1.0 * (-b - sq) / 2 * a;if(x1 > x2)print_division(-b + sq, 2 * a);elseprint_division(-b - sq, 2 * a);puts("");return;}if(b) {print_division(-b, 2 * a);putchar('+');}print_sqrt(delta, 2 * a);puts("");
}int main() {scanf("%d%d", &T, &m);while(T-- && scanf("%d%d%d", &a, &b, &c))work(a, b, c);return 0;
}

提交結果

戳這里看我的提交記錄
提交結果

尾聲

如果這篇題解對您(或您的團隊)有幫助的話,就幫忙點個贊,加個關注!

最后,祝您(或您的團隊)在 OI 的路上一路順風!!!

┬┴┬┴┤?ω?)ノ Bye~

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/696146.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/696146.shtml
英文地址,請注明出處:http://en.pswp.cn/news/696146.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

STM32G030C8T6:定時器1ms中斷(以64MHz外部晶振為例)

本專欄記錄STM32開發各個功能的詳細過程&#xff0c;方便自己后續查看&#xff0c;當然也供正在入門STM32單片機的兄弟們參考&#xff1b; 本小節的目標是&#xff0c;系統主頻64 MHZ,采用高速外部晶振&#xff0c;通過定時器3 每秒中斷控制 PB9 引腳輸出高低電平&#xff0c;從…

20240222作業

完善對話框&#xff0c;點擊登錄對話框&#xff0c;如果賬號和密碼匹配&#xff0c;則彈出信息對話框&#xff0c;給出提示“登錄成功"&#xff0c;提供一個Ok按鈕&#xff0c;用戶點擊OK后&#xff0c;關閉登錄界面&#xff0c;跳轉到其他界面 如果賬號和密碼不匹配&…

Java基礎-注解

注解 注解是用來干什么的它有什么作用注解的常見分類內置注解Override注解定義 Deprecated注解定義 SuppressWarnings注解定義 元注解Target注解定義ElementType Retention&&RetentionTarget注解定義RetentionPolicy Documented注解定義 Inherited注解定義用法 Repeata…

低代碼開發:推動互聯網企業數字化轉型的關鍵因素

聯網行業作為我國數字經濟發展的核心驅動力&#xff0c;在推動國家數字化轉型中扮演著至關重要的角色。與其他傳統行業相比&#xff0c;互聯網企業面臨更加緊迫的數字化轉型需求&#xff0c;因為它們需要不斷適應快速變化的市場環境和技術趨勢。 然而&#xff0c;由于互聯網企業…

深入理解APDU協議與Java開發

1. 什么是APDU&#xff1f; APDU&#xff0c;即應用協議數據單元&#xff08;Application Protocol Data Unit&#xff09;&#xff0c;是一種在智能卡與卡片讀卡器之間進行通信的協議。APDU定義了在交互中傳輸的數據格式和規則&#xff0c;允許讀卡器發送指令并接收響應。 2…

MFC 皮膚庫配置

1.創建MFC 對話框 2.添加皮膚資源 添加資源 添加頭文件 關閉SDL檢測 添加靜態庫文件 修改字符集 添加頭文件 將皮膚中的ssk文件加載到初始化實例中 > 運行即可

springboot 的 websocket 里面使用 @Autowired 注入 service 或 bean 時,報空指針異常

直接上解決方案&#xff1a; 在你的WebSocketServer服務器中 public static MessageService messageService; //要注入的類// 注入的時候&#xff0c;給類的 service 注入Autowiredpublic void setChatService(MessageService messageService) {WebSocketServer.messageSer…

【寸鐵的刷題筆記】樹、dfs、bfs、回溯、遞歸(一)

【寸鐵的刷題筆記】樹、dfs、bfs、回溯、遞歸(一) 大家好 我是寸鐵&#x1f44a; 總結了一篇刷題關于樹、dfs、bfs、回溯、遞歸的文章? 喜歡的小伙伴可以點點關注 &#x1f49d; 105. 從前序與中序遍歷序列構造二叉樹 模擬分析圖 代碼實現 /*** Definition for a binary tre…

HarmonyOS—添加/刪除Module

Module是應用/服務的基本功能單元&#xff0c;包含了源代碼、資源文件、第三方庫及應用/服務配置文件&#xff0c;每一個Module都可以獨立進行編譯和運行。一個HarmonyOS應用/服務通常會包含一個或多個Module&#xff0c;因此&#xff0c;可以在工程中創建多個Module&#xff0…

如何利用內網穿透工具在企業微信開發者中心實現本地接口服務回調

文章目錄 1. Windows安裝Cpolar2. 創建Cpolar域名3. 創建企業微信應用4. 定義回調本地接口5. 回調和可信域名接口校驗6. 設置固定Cpolar域名7. 使用固定域名校驗 企業微信開發者在應用的開發測試階段&#xff0c;應用服務通常是部署在開發環境&#xff0c;在有數據回調的開發場…

SQL查詢每個類別價格前3的數據

SELECTproduct_id,category,price FROM (SELECTproduct_id,category,price,ROW_NUMBER() OVER (PARTITION BY category ORDER BY price) AS rankFROMyour_products_table ) AS ranked_products WHERErank < 3;DENSE_RANK() 和 ROW_NUMBER() 是窗口函數&#xff08;Window Fu…

前端知識復習

1.symbol類型 Symbol 是 ECMAScript 6 中引入的一種新的基本數據類型&#xff0c;它表示獨一無二的值。Symbol 值是通過 Symbol() 函數創建的。 Symbol 值具有以下特點&#xff1a; 獨一無二性&#xff08;唯一性&#xff09;&#xff1a;每個通過 Symbol() 函數創建的 Symb…

十三:集合

提示&#xff1a;文章寫完后&#xff0c;目錄可以自動生成&#xff0c;如何生成可參考右邊的幫助文檔 文章目錄 01、Java 集合框架概述1.1、集合框架與數組的對比及概述1.2、集合框架涉及到的API 02、Collection接口方法2.1、Collection接口中的常用方法12.2、Collection接口中…

在idea中配置Tomcat

1.在idea中點擊右上角 2.點擊Edit Configurations,點擊加號 3.向下拉找到Tomcat Server下的Local,點一下 點擊Configure 找到tomcat文件路徑,選擇apache-tomcat-8.5.63(8.5.63是我的版本號) 選擇好路徑后點ok就配置好了 總步驟:

Vue 圖片輪播第三方庫 Vue-awesome-swiper介紹及簡單例子

vue-awesome-swiper 是一個基于 Swiper 的 Vue 輪播圖組件&#xff0c;Swiper 是一個流行的移動端觸摸滑動插件。它為 Vue.js 應用提供了一套豐富的輪播組件&#xff0c;支持多種布局和功能&#xff0c;如自動播放、無限循環、觸摸滑動等。 安裝 首先&#xff…

代碼隨想錄算法訓練營第一天

● 今日學習的文章鏈接和視頻鏈接 ● 自己看到題目的第一想法 1. 704二分法&#xff1a; 方法一&#xff1a; 整個數組是 左閉右閉區間 [ ] left指針指向數組開始下標&#xff0c; right 指針指向數組最后下表nums.size()-1, mid為 (leftright) /2循環條件 left<rightnu…

打開stable diffusion webui時,提示缺少clip或clip安裝不上的解決方案(windows下的操作)

1.問題描述 打開stable diffusion webui時&#xff0c;提示缺少clip或clip安裝不上 2.解決方案 原因&#xff1a;stable diffusion webui環境中的clip其實是open_clip&#xff0c;不能用pip install clip安裝解決方法是直接到github下載 open_clip 代碼到本地&#xff0c;并…

linux環境ssh-rsa進行簽名\權限\登錄\原理(免密登錄)

linux環境ssh-rsa進行簽名權限登錄(免密登錄) SSH原理與運用什么是SSH?SSH的使用場景ssh-rsa獲取xshell環境登錄獲取ssh-rsa使用ssh-rsa登錄SHA系列SHA-1、SHA-256和RSA的區別RSA原理數論基礎RSA機制RSA數學密鑰生成公式RSA數學加密理論RSA數學簽名公式

小折疊也能成為主力機,全新小折疊旗艦華為Pocket 2正式發布

2024年2月22日&#xff0c;華為在三亞舉辦華為Pocket 2時尚盛典&#xff0c;正式發布其全新小折疊旗艦華為Pocket 2。一直以來&#xff0c;華為致力于萃取各界藝術靈感&#xff0c;不斷探尋科技美學的可能性&#xff0c;華為Pocket系列更是秉承將奢雅美學與尖端科技融為一體的理…

探索Redis是否為單線程的奧秘(文末送書)

&#x1f308;個人主頁&#xff1a;聆風吟 &#x1f525;系列專欄&#xff1a;數據結構、網絡奇遇記 &#x1f516;少年有夢不應止于心動&#xff0c;更要付諸行動。 文章目錄 &#x1f4cb;前言一. Redis中的多線程二. I/O多線程三. Redis中的多進程四. 結論五. 書籍推薦5.1 書…