日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

历史上的今天(history)+ 勇者斗恶龙(dragon)

發布時間:2023/12/3 编程问答 42 豆豆
生活随笔 收集整理的這篇文章主要介紹了 历史上的今天(history)+ 勇者斗恶龙(dragon) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

朋友們我來了,好久都沒有更新了,手實在癢癢,不擼兩道,內心過意不去

文章目錄

  • A:歷史上的今天(history)
    • 題目
    • 題解
    • 代碼實現
  • B: 勇者斗惡龍(dragon)
    • 題目描述
    • 題解
    • 代碼實現

A:歷史上的今天(history)

題目

小 P 是一個普通的高中生。自從進入高中以來,作業一天比一天多,每天都要熬夜趕作業。
而今天,他還需要多做一件事情——為明天歷史課準備上課前三分鐘的《歷史上的今天》演講稿。
小 P 十分喜歡研究歷史,他的電腦里存了 個他最喜歡的歷史事件,每個歷史事件都由年,月,日以及事件名稱構成。由于小 P 整理資料時有一些混亂,所以歷史事件中可能有未來(當前時間點并沒有發生過)的事件。
現在,為了準備演講稿,小 P 急需知道有多少歷史事件發生在歷史上的明天。然而他喜歡的歷史事件實在是太多了,以至于難以查找。 你能夠幫助他嗎?

一個事件發生在歷史上的當天,當且僅當該事件發生在當天或當天之前,且除年份以外,月份和天數在數值上都相同。 你需要按照時間順序從小到大輸出這些歷史事件的名稱。數據保證不存在發生在同一天的兩個歷史事件,但可能存在兩個事件名稱相同。

輸入格式
第一行一個字符串 date0,表示今天的日期。
第二行一個整數 n,表示小 P 喜歡的歷史事件的數量。
接下來 n 行,每行兩個字符串 datei, namei,分別表示第 i 個歷史事件發生的日期,以及該歷史事件的名稱。
字符串 datei (0 <= i <= n)的格式為 year.month.day 即三個數 year, month, day 分別為年份,月份,天數的數值,中間用.隔開,且保證當前日期一定合法。
為了讀入方便,我們規定 year, month, day 的位數分別嚴格為 4位,2位,2位,不足該位數的用 0 補齊。例如,2019年九月九日表示為2019.09.09,2020年七月二十四日表示為2020.07.24。
字符串namei (1 <= i <= n)保證只由數字(0-9),小寫字母(a-z),大寫字母(A-Z),以及下劃線(_)構成,長度不超過40。

輸出格式
第一行一個數字 k(1 <= k <= n) ,表示滿足條件的歷史事件的數量。
接下來 k 行,每行一個字符串 namei ,表示你認為時間第 i 小的符合上述條件的歷史事件的名稱。
如果沒有任何滿足要求的歷史事件,輸出第一行即可。

樣例
樣例1
2019.09.09
5
2019.10.07 Double_Ninth_Festival
2020.07.24 The_2020_Tokyo_Olympic_Games
2019.09.10 35th_Teachers_day
2022.02.04 The_2022_Beijing_Olympic_Winter_Games
1985.09.10 Chinese_Teachers_day
樣例1
2
Chinese_Teachers_day
35th_Teachers_day
樣例2
2019.11.16
7
2017.11.16 Tiw_AK_NOIP2017
2018.11.16 Tiw_AK_NOIP2018_day1
2018.11.17 Tiw_AK_NOIP2018_day2
2019.11.17 Tiw_AK_CSP2019_day2
2019.11.16 Tiw_AK_CSP2019_day1
2020.11.17 Tiw_AK_CSP2020_day2
2020.11.16 Tiw_AK_CSP2020_day1
樣例2
2
Tiw_AK_NOIP2018_day2
Tiw_AK_CSP2019_day2
樣例3
2024.10.31
20
0401.11.01 history
1539.11.01 history
0259.11.01 history
1955.11.01 history
0663.11.01 history
0372.11.01 history
0270.11.01 history
0047.11.01 history
0465.11.01 history
0036.11.01 history
1188.11.01 history
1367.11.01 history
1142.11.01 history
1820.11.01 history
0058.11.01 history
0153.11.01 history
0557.11.01 history
1959.11.01 history
1074.11.01 history
0152.11.01 history
樣例3
20
history
history
history
history
history
history
history
history
history
history
history
history
history
history
history
history
history
history
history
history
數據范圍與提示
【樣例 1 解釋】
只有第 3 個和第 5 個歷史事件滿足條件。
注意要按照時間順序從小到大輸出,未來的時間點應該直接忽視掉。
【樣例 2 解釋】
綜上可以得出結論:歷史總是驚人的相似。

題解

這道題完全就是一個純粹的模擬,
處理出來所有日期是歷史上的明天的i,再判斷年份是不是已經發生
丟到一個數組里面排序輸出就好了

唯一麻煩的就是處理一下明天的特殊性,
比如剛好是二月,剛好是閏年,剛好是一個月的最后一天,剛好是一年的最后一個月…
本來是一道簡單的模擬,硬生生掰成了手打if-else

送你一個小秘籍→

代碼實現

#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; #define MAXN 10005 struct node {int year, num; }result[MAXN]; int n, tot, year, month, day; string opt; string name[MAXN], date[MAXN];bool run ( int a ) {if ( ( a % 4 == 0 && a % 100 != 0 ) || ( a % 400 == 0 && a % 3200 != 0 ) )return 1;return 0; }void init () {day ++;if ( month == 2 ) {if ( run ( year ) ) {if ( day == 30 ) {month = 3;day = 1;}}else {if ( day == 29 ) {month = 3;day = 1;}}}else {if ( month == 1 || month == 3 || month == 5 || month == 7 || month == 8 || month == 10 || month == 12 ) {if ( day == 32 ) {month ++;day = 1;}}else {if ( day == 31 ) {month ++;day = 1;}}}if ( month == 13 ) {month = 1;year ++;} }bool cmp ( node x, node y ) {return x.year < y.year; }int main() {cin >> opt;int len = opt.length();for ( int i = 0;i < len;i ++ ) {if ( i < 4 )year = year * 10 + ( opt[i] - '0' );if ( i >= 5 && i <= 6 )month = month * 10 + ( opt[i] - '0' );if ( i >= 8 && i <= 9 )day = day * 10 + ( opt[i] - '0' );}init ();scanf ( "%d\n", &n );for ( int i = 1;i <= n;i ++ ) {cin >> date[i] >> name[i];int y = 0, m = 0, d = 0;for ( int j = 0;j < len;j ++ ) {if ( j < 4 )y = y * 10 + ( date[i][j] - '0' );if ( j >= 5 && j <= 6 )m = m * 10 + ( date[i][j] - '0' );if ( j >= 8 && j <= 9 )d = d * 10 + ( date[i][j] - '0' );}if ( m == month && d == day && y <= year ) {result[++ tot].year = y;result[tot].num = i;}}sort ( result + 1, result + tot + 1, cmp );printf ( "%d\n", tot );for ( int i = 1;i <= tot;i ++ )cout << name[result[i].num] << endl;return 0; }

B: 勇者斗惡龍(dragon)

題目描述

現在有一條 n 頭龍,生命值為 h,勇士想要打敗這條作惡多端的龍。

勇士攻擊第 i 個頭會造成 min(h,atki) 點傷害,即龍的生命值減少 min(h,atki) 點;但龍的第 i 個頭受到傷害后會恢復 di 點生命值,即生命值增加 di 。 勇士無法重復攻擊同一個頭,即他對于每個頭最多只能攻擊一次。當龍的生命值為 o 時則視為被勇士打敗,此時它不能再恢復生命值了。 勇士想要知道他是否能打敗這頭龍,如果能打敗最少需要攻擊多少次。

輸入格式
第一行包含兩個整數 n,h,分別表示龍的頭的數量和龍的生命值。
接下來 n 行,每行兩個整數atki,di,含義見【題目描述】。
輸出格式
第一行輸出 Yes 或 No,表示勇士是否能擊敗惡龍若能擊敗。
如果能打敗,在第二行輸出一個整數,表示打敗這頭龍所需的最小攻擊次數。

樣例
樣例1
3 5
2 3
2 0
1 0
樣例1
Yes
3
樣例2
3 6
2 3
2 0
1 0
樣例2
No
【樣例 1 解釋】 只要最后一次攻擊第一個頭,就能剛好擊敗惡龍。
數據范圍與提示

題解

首先這道題很好想的就是貪心
按照atki-di從大到小排序,這樣越靠前的i對巨龍的傷害越高,答案個數也就能越小
做到這就能85分了

然后就去枚舉最后一擊,那么如果打其他頭造成的攻擊力為atki-di
因為其他攻擊都打不死它,

這里就可以找到一種貪心策略
首先將所有頭按照atki-di從大到小排序,
然后每次固定一個頭后找出至少需要前面多少個頭atki-di之和相加大于h-atkx,x是你選中的最后一擊,
時間復雜度n2

這樣肯定是TLE,于是我們考慮優化,我們可以排序后統計
出atki-di的前綴和si,那么我們只需要針對h-atki和sx-1大小關系分類討論二分即可,
時間復雜度nlogn

但是這里也只有95
還有你會發現,這個時候處理出來的s數組并不具有單調性
二分很危險!!!

其實atki ≤ di的情況是根本不需要的,
它對于答案只會增加惡龍的生命值,我們要把它排除掉,i - -,n - -
這個時候s數組就會具有單調性了

問題又來了,很有可能最后一擊atkx ≤ di
但是惡龍在被攻擊后就生命值0了,題意說這個時候它無法回血,
這就意味著,這最后一擊很有可能在上面被我們自作聰明地排除掉

所以我們就不能i - -,n - -,直接在s數組上動手腳就可以了

解決完這些問題后,注意到一組特判
看好h的數據范圍,有可能為0,
這意味著有可能剛一上場,惡龍就被嚇得尿尿了

你的答案就應該是0而不是1

代碼實現

#include <cstdio> #include <iostream> #include <algorithm> using namespace std; #define MAXN 300005 #define LL long long #define INF 0x7f7f7f7f int n, h, result = INF, inter; LL s[MAXN];struct node {LL atk, d; }a[MAXN];bool cmp ( node x, node y ) {return x.atk - x.d > y.atk - y.d; }void solve ( int l, int r, LL val ) {if ( l > r ) return;int mid = ( l + r ) >> 1;if ( s[mid] >= val ) {inter = min ( inter, mid );if ( l == mid ) return;solve ( l, mid, val );}else solve ( mid + 1, r, val ); }int main() {scanf ( "%d %d", &n, &h );for ( int i = 1;i <= n;i ++ )scanf ( "%lld %lld", &a[i].atk, &a[i].d );if ( h == 0 ) return ! printf ( "Yes\n0" );sort ( a + 1, a + n + 1, cmp );for ( int i = 1;i <= n;i ++ )if ( a[i].atk <= a[i].d ) s[i] = s[i - 1];else s[i] = s[i - 1] + a[i].atk - a[i].d;for ( int i = 1;i <= n;i ++ ) { inter = INF;if ( h <= a[i].atk ) return ! printf ( "Yes\n1" );solve ( 1, i - 1, h - a[i].atk );result = min ( result, inter + 1 );}if ( result == INF )printf ( "No" );elseprintf ( "Yes\n%d", result );return 0; }

好了,今天就先制作這兩道吧,幾天后再完成后面兩道
有任何問題歡迎指出,也可以給我建議寫博客的一些小細節。我們下期再見。。。

總結

以上是生活随笔為你收集整理的历史上的今天(history)+ 勇者斗恶龙(dragon)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。