『ACM C++』HDU杭電OJ | 1416 - Gizilch (DFS - 深度優先搜索入門)

来源:https://www.cnblogs.com/winniy/archive/2019/02/27/10447645.html
-Advertisement-
Play Games

從周三課開始總算輕鬆了點,下午能在宿舍研究點題目啥的打一打,還好,剛開學的課程還算跟得上,剛開學的這些課程也是複習以前學過的知識,下半學期也不敢太划水了,被各種人寄予厚望之後瑟瑟發抖,只能努力前行了~自己好多地方還做得不夠好,真的是要提升的方面太多了,加油吧~ 今日興趣新聞: 網易回應裁員:公司確實 ...


 

  從周三課開始總算輕鬆了點,下午能在宿舍研究點題目啥的打一打,還好,剛開學的課程還算跟得上,剛開學的這些課程也是複習以前學過的知識,下半學期也不敢太划水了,被各種人寄予厚望之後瑟瑟發抖,只能努力前行了~自己好多地方還做得不夠好,真的是要提升的方面太多了,加油吧~

 

 

今日興趣新聞:

網易回應裁員:公司確實正在進行結構性優化

鏈接:https://baijiahao.baidu.com/s?id=1626619207432301200&wfr=spider&for=pc

偶爾反新聞經常看到這些大公司的裁員,谷歌、微軟、華為、百度都出現過大幅度的裁員,現在網易也開始了,這會不會加劇了未來畢業職業出口的緊張呢?

 

 

------------------------------------------------題目----------------------------------------------------------

Gizilch

Problem Description

The game of gizilch has very simple rules. First 100 grapes are labeled, in nontoxic ink, with the numbers 1 to 100. Then, with a cry of ``GIZILCH!'', the referee fires the grapes up into the air with a giant gizilcher. The two players, who each start with a score of ``1'', race to eat the falling (or, shortly thereafter, fallen) grapes and, at the same time, multiply their scores by the numbers written on the grapes they eat. After a minute, the hungry squirrels are let loose to finish the remaining grapes, and each contestant reports his score, the product of the numbers on the grapes he's eaten. The unofficial winner is the player who announces the highest score.
Inevitably, though, disputes arise, and so the official winner is not determined until the disputes are resolved. The player who claims the lower score is entitled to challenge his opponent's score. The player with the lower score is presumed to have told the truth, because if he were to lie about his score, he would surely come up with a bigger better lie. The challenge is upheld if the player with the higher score has a score that cannot be achieved with grapes not eaten by the challenging player. So, if the challenge is successful, the player claiming the lower score wins.
So, for example, if one player claims 343 points and the other claims 49, then clearly the first player is lying; the only way to score 343 is by eating grapes labeled 7 and 49, and the only way to score 49 is by eating a grape labeled 49. Since each of two scores requires eating the grape labeled 49, the one claiming 343 points is presumed to be lying.
On the other hand, if one player claims 162 points and the other claims 81, it is possible for both to be telling the truth (e.g. one eats grapes 2, 3 and 27, while the other eats grape 81), so the challenge would not be upheld.
Unfortunately, anyone who is willing to referee a game of gizilch is likely to have himself consumed so many grapes (in a liquid form) that he or she could not reasonably be expected to perform the intricate calculations that refereeing requires. Hence the need for you, sober programmer, to provide a software solution.

Input

Pairs of unequal, positive numbers, with each pair on a single line, that are claimed scores from a game of gizilch.

Output

Numbers, one to a line, that are the winning scores, assuming that the player with the lower score always challenges the outcome.

Sample Input

343 49
3599 610
62 36

Sample Output

49 
610 
62

------------------------------------------------題目----------------------------------------------------------

 

(一) 原題大意:

    原意說的是有一到一百個葡萄,有兩個人去吃這些葡萄,每個葡萄上面有數字,每個人吃到的葡萄乘積之和就是自己的答案,獲得最大的數就是勝利,但有人為了勝利會假報自己的數字,讓你去識破他。

    簡單來說,就是一個游戲:

    有兩個人玩游戲A、B人,A和B都報一個數,其中最大的人是被挑戰者,最小的那個人是挑戰者,然後兩人的數通過因式分解,若挑戰者中總存在一種分解,是被挑戰者總有的因數,那麼說明被挑戰者說謊,判挑戰者勝利。

    舉例:

    A = 343 B = 49 顯然A>B,那麼A是被挑戰者,B是挑戰者,正常來說較小的人不說假話,因為如果他要說假話為何不往大的數說呢,好讓自己贏。

    所以對A、B進行因式分解,對於B來說,你只能吃49才能得到,所以A不能再使用49了,但是A可以因式分解成49 * 7,所以可以看得出來A說了假話,判B勝利~

 

 

(二) 題目分析:

    這道題有點小難度對於新手的我來說,查閱了一些解法加之自己的理解,是需要用到遞歸的DFS深搜方法去實現的。

    首先建立一個數組,用來存儲100個葡萄,value為0則說明還沒被吃,1說明已經吃過不能再吃了,通過這種方法來判斷A、B是否有因數重覆。

    然後對挑戰者進行因式分解,得到挑戰者的因式分解,然後再對被挑戰者進行因式分解,如果被挑戰者能夠順利的因式分解,那麼被挑戰者獲勝,否則挑戰者獲勝。

    後面我會簡單整理一下深搜筆記~

 

(三) 代碼分塊:

    第一步:分清挑戰者和被挑戰者:

        if(a>b)
        {
            attacker = b;
            victim = a;
        }
        else
        {
            attacker = a;
            victim = b;
        }

    第二步:對挑戰者進行因式分解:

result_dfs = dfs(attacker);

    這裡需要自己定義dfs深搜函數,那麼下麵開始定義深搜dfs:

    第三步:dfs函數構造:分解因式:

    if(number > 100) size = 100;
    else size = number;
    
    for(i = 2 ; i<= size ; i++)
    {
        if( number %i == 0 && already[i] == 0)
        {
            already[i] = 1;
            if(dfs( number / i ) == 1) return 1;
            already[i] = 0;
        }
    }

    第四步:dfs函數構造:判斷挑戰者和被挑戰者的因式分解情況:

    if(number == 1)
    {
        if(vic_divided == 0)
        {
            vic_divided = 1;
            vic_divide = 1;
            if(dfs(victim) == 1) return 1;
            else{
                vic_divided = 0;
                return 0;
            }
        }
        return 1;
    }

    第五步,根據dfs返回的結果判斷勝負:

        if(vic_divided == 1 && result_dfs == 1 || vic_divide == 0)    winner = victim;
        else winner = attacker;

 

 

(四) AC代碼:

#include<stdio.h>
#include<string.h>

int attacker,victim;
int vic_divided,vic_divide;
int already[101];


int dfs(int number)
{
    int i,size;
    
    if(number == 1)
    {
        if(vic_divided == 0)
        {
            vic_divided = 1;
            vic_divide = 1;
            if(dfs(victim) == 1) return 1;
            else{
                vic_divided = 0;
                return 0;
            }
        }
        return 1;
    }
    
    if(number > 100) size = 100;
    else size = number;
    
    for(i = 2 ; i<= size ; i++)
    {
        if( number %i == 0 && already[i] == 0)
        {
            already[i] = 1;
            if(dfs( number / i ) == 1) return 1;
            already[i] = 0;
        }
    }
    return 0;
}

int main()
{
    int a,b,result_dfs,winner;
    while(scanf("%d %d",&a,&b) != EOF)
    {
        vic_divide = vic_divided = 0;
        memset(already, 0, sizeof(already));
        if(a>b)
        {
            attacker = b;
            victim = a;
        }
        else
        {
            attacker = a;
            victim = b;
        }
        
        result_dfs = dfs(attacker);
        
        if(vic_divided == 1 && result_dfs == 1 || vic_divide == 0)    winner = victim;
        else winner = attacker;
        
        printf("%d\n",winner);
    }
    return 0;
 } 

 

 

(五)AC截圖:

 

(六) 解後分析:

    這道題用到了深搜,即深度優先搜索,簡稱DFS,對應的還有BFS,廣度優先搜索。

    事實上,深度優先搜索屬於圖演算法的一種,英文縮寫為DFS即Depth First Search.其過程簡要來說是對每一個可能的分支路徑深入到不能再深入為止,而且每個節點只能訪問一次。

    

     如果我們從A點發起深度優先搜索(以下的訪問次序並不是唯一的,第二個點既可以是B也可以是C,D),則我們可能得到如下的一個訪問過程:A->B->E(沒有路了!回到A)->C->F->H->G->D(沒有路,最終回到A,A也沒有未訪問的相鄰節點,本次搜索結束)

    深度優先遍歷圖的方法是,從圖中某頂點v出發:     (1)訪問頂點v;     (2)依次從v的未被訪問的鄰接點出發,對圖進行深搜遍歷;直至圖中和v有路徑相通的頂點都被訪問;     (3)若此時圖中尚有頂點未被訪問,則從一個未被訪問的頂點出發,重新進行深搜遍歷,直到圖中所有頂點均被訪問過為止。

     參考:https://baike.baidu.com/item/深度優先搜索/5224976

    做了幾道題之後,簡單悟到一些使用BFS、DFS的一些方式,但還很淺顯,需要加強題量練習提升自己:

    =》BFS是用來搜索最短徑路的解是比較合適的,比如求最少步數的解,最少交換次數的解。

    =》DFS不需要保存搜索過程中的狀態,而BFS在搜索過程中需要保存搜索過的狀態,而且一般情況需要一個隊列來記錄。

    =》DFS適合搜索全部的解,因為要搜索全部的解,那麼BFS搜索過程中,遇到離根最近的解,並沒有什麼用,也必須遍歷完整棵搜索樹,DFS搜索也會搜索全部,但是相比DFS不用記錄過多信息,所以搜素全部解的問題,DFS顯然更加合適。

 

 

註:我還是個渣渣輝,代碼可能寫得不夠高效不夠好,我也會努力優化,如果有更好的解法,真心希望您能夠評論留言貼上您的代碼呢~互相幫助互相鼓勵才能成長鴨~~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 題意 "題目鏈接" Sol 好像搞出了一個和題解不一樣的做法(然而我考場上沒寫出來還是爆零0) 一個很顯然的思路是考慮每個最小值的貢獻。 預處理出每個數左邊第一個比他小的數,右邊第一個比他大的數。 那麼$[L_i + 1, i]$對$[i, R_i]$中的每個數都會有$a[i]$的貢獻。 我們可以抽 ...
  • pip如今已經成為了Python的一大特色,可以很方便得協助Python開發者進行包管理。本文詳細介紹了pip命令的使用方法。 ...
  • __getattribute__ 官方文檔中描述如下: 該方法可以攔截對對象屬性的所有訪問企圖,當屬性被訪問時,自動調用該方法(只適用於新式類)。因此常用於實現一些訪問某屬性時執行一段代碼的特性。 需要註意的是,正式由於它攔截對所有屬性的訪問(包括對__dict__的訪問),在使用中要十分小心地避開 ...
  • IT是全國平均薪資最高的行業,2017年全國最高,人均13點4萬每年. 但技術固然好,創業拼的還是世界觀下的創意. 蘑菇街,並夕夕,TikTok,頭條,哪個不是創意用IT技術的現實化?? 未來,大平臺是Dio絲(歐拉木大)用的,中等偏上的人還是會用個人定製...上等人我不知道 加油吧,未來引擎是服務 ...
  • 發個致富腦洞:我就在想本人雖然單身,但本人戀愛經歷很多,追女生技術十足,女朋友漂亮又賢惠.如果本人開個平臺幫人誠心介紹女朋友,男女成男女朋友經男方同意我收2.5萬(IT界平均月收入的1.5倍不到),雙方結婚我再收2.5萬,總共5萬.如果沒結婚隨時可退錢,房產證做抵押,不知道行不行啊...本著給極少數 ...
  • 觀察者模式 嗨,大家好,我們又見面了,不知道上次的籃球比賽大家是不是還意猶未盡呢,沒看到的同學可以前往https://www.cnblogs.com/MrJR/p/10441166.html觀摩哦。 今天呢,我們來看另一個Java設計模式——觀察者模式。 顧名思義,觀察者模式,那肯定要有觀察者,既然 ...
  • 定義: CDN 即內容分佈網路,(Content Delivery Netwrok) ,是構築在現有Internet上的一種先進的流量分配網路,其目的是通過在現有的Internet中增加一層新的網路架構,將網站的內容發佈到最接近用戶的網路“邊緣”,使用戶可以就近取得所需的內容,提高用戶訪問網站的相應 ...
  • 文件鎖 當多個進程或多個程式都想要修同一個文件的時候,如果不加控制,多進程或多程式將可能導致文件更新的丟失。 例如進程1和進程2都要寫入數據到a.txt中,進程1獲取到了文件句柄,進程2也獲取到了文件句柄,然後進程1寫入一段數據,進程2寫入一段數據,進程1關閉文件句柄,會將數據flush到文件中,進 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...