這次競賽還是存在些許bug,題目難度中等,沒有特別難的題目,也沒有送分題。被bug和一些題目的數(shù)據(jù)卡了一段時間,最終通過還是花了不少時間的。
創(chuàng)新互聯(lián)建站-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比吳江網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式吳江網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋吳江地區(qū)。費用合理售后完善,10年實體公司更值得信賴。題目列表 1.豚鼠排名榜 題目描述已知字符A.B,C。每個字符都有自己的權(quán)值q。
現(xiàn)不知道權(quán)值q,只知道A,B,C的三次比較結(jié)果。
輸入描述:
輸入三個字符串表示三次比較的結(jié)果
輸出描述:
輸出結(jié)果,如果不存在輸出”Impossible”
輸入樣例:
A
B>C
C>A
輸出樣例:
ACB
分析首先,吐槽下這題的自測輸入的bug,考試環(huán)境輸入 < < <會被自動轉(zhuǎn)化為 & l t \< <,所以你用自測輸入來測試程序會一直出錯,這點卡了我挺久,檢查和修改了若干遍代碼后,才發(fā)現(xiàn)自測輸入有問題。貌似在評論區(qū)回復(fù)小于號也會自動轉(zhuǎn)化為 & l t \< <。
題目意思給的輸入應(yīng)該是ABC兩兩比較的結(jié)果,三次比較結(jié)果矛盾就輸出”Impossible”,這里輸出結(jié)果不存在我理解為是出現(xiàn) A < B , B < C , C < A A A , C < B AA,CA,C
考試時我的想法是:既然是T1,肯定是思路越簡單越好,題意輸出結(jié)果不存在的情況應(yīng)該就是出現(xiàn)矛盾的情況。所以要想完整表示三個字符間的偏序關(guān)系,必然會出現(xiàn)一個字符大于其他兩個,一個字符大于另一個,那么比字符小的字符個數(shù)依次是012,就比如用例,從小到大是ACB,那么A大于0個字符,C大于1個字符,B大于2個字符。我們遍歷輸入三個表達式的時候統(tǒng)計下每個字符大于其他字符的次數(shù),如果最終三個字符大于其他字符的次數(shù)分別是0,1,2,結(jié)果就是合理的,否則輸出”Impossible”。
代碼#include#include#include#includeusing namespace std;
unordered_mapm;
std::string solution(std::string exp1, std::string exp2, std::string exp3) {vectort = {exp1,exp2,exp3};
m['A'] = m['B'] = m['C'] = 0;
for(auto x : t) {if (x[1] == '>') m[x[0]]++;
else m[x[2]]++;
}
string res = "ABC";
int cnt[3] = {0};
for (auto x : m) {cnt[x.second]++;
res[x.second] = x.first;
}
for(int i = 0; i< 3; i++) {if(cnt[i] != 1) return "Impossible";
}
return res;
}
int main() {std::string exp1;
std::string exp2;
std::string exp3;
cin>>exp1;
cin>>exp2;
cin>>exp3;
std::string result = solution(exp1, exp2, exp3);
std::cout<
2.字符串轉(zhuǎn)換
題目描述已知一個字符串a(chǎn),b。 字符串b中包含數(shù)量不等的特殊符號“.”,“*”(字符串存在沒有特殊符號或者全由特殊符號組成的情 況)。 “.”表示該字符可以變成任意字符,“* ”表示該字符的前一個字符可以變成任意多個。 現(xiàn)在我們想知道b可否通過特 殊符號變成a。 a* 可以轉(zhuǎn)化為a,aa,aaa,aaaa…
分析這道題對于會做的同學(xué)很簡單,可以說能做出來的肯定做過這道題,因為如果連這么經(jīng)典的題都沒做過,那么一般做不出來這道題,對于第一次遇見這道題的同學(xué)來說,難度還是不小的。之前寫的這道題的題解AcWing 30 正則表達式匹配。
這道題與正則表達式匹配還是有點區(qū)別的,因為正則表達式匹配中*可以使得前面字符出現(xiàn)0次,處理起來更加復(fù)雜,而本題指出了*前面字符至少出現(xiàn)一次,這樣處理起來就簡單了。
狀態(tài)表示: f [ i ] [ j ] f[i][j] f[i][j]表示 a a a的前 i i i個字符與 b b b的前 j j j個字符是否匹配, t r u e true true表示匹配, f a l s e false false表示不匹配。
狀態(tài)邊界: f [ 0 ] [ 0 ] = t r u e f[0][0]=true f[0][0]=true表示兩個字符串都是空的情況是匹配的。
狀態(tài)轉(zhuǎn)移方程:
b
[
j
?
1
]
?
!
=
?
′
?
′
b[j-1] \ !=\ '*'
b[j?1]?!=?′?′時,
f
[
i
]
[
j
]
=
{
f
[
i
?
1
]
[
j
?
1
]
if?
a
[
i
?
1
]
=
=
b
[
j
?
1
]
?
o
r
?
b
[
j
?
1
]
=
=
′
.
′
f
a
l
s
e
,
a
[
i
?
1
]
!
=
b
[
j
?
1
]
?
a
n
d
?
b
[
j
?
1
]
!
=
′
.
′
f[i][j]= \begin{cases} f[i-1][j-1]& \text{if\ $a[i-1]==b[j-1]\ or\ b[j-1]=='.'$}\\ \\ false,& \text{$a[i-1]!=b[j-1]\ and\ b[j-1]!='.'$} \end{cases}
f[i][j]=??????f[i?1][j?1]false,?if?a[i?1]==b[j?1]?or?b[j?1]==′.′a[i?1]!=b[j?1]?and?b[j?1]!=′.′?
b [ j ? 1 ] ? = = ? ′ ? ′ b[j-1] \ ==\ '*' b[j?1]?==?′?′時,
f [ i ] [ j ] = { f a l s e , if? b [ j ? 2 ] ? ! = ? a [ i ? 1 ] ?and? b [ j ? 2 ] ? ! = ? ′ . ′ f [ i ? 1 ] [ j ] ? ∣ ? f [ i ] [ j ? 1 ] , if? b [ j ? 2 ] ? = = ? a [ [ i ? 1 ] ?or? b [ j ? 2 ] ? = = ? ′ . ′ f[i][j]= \begin{cases} false, & \text{if\ $b[j-2]\ !=\ a[i-1]$\ and\ $b[j-2]\ !=\ '.'$}\\ \\ f[i-1][j]\ |\ f[i][j-1],& \text{if\ $b[j-2]\ ==\ a[[i-1]$\ or\ $b[j-2]\ ==\ '.'$} \end{cases} f[i][j]=??????false,f[i?1][j]?∣?f[i][j?1],?if?b[j?2]?!=?a[i?1]?and?b[j?2]?!=?′.′if?b[j?2]?==?a[[i?1]?or?b[j?2]?==?′.′?
由于狀態(tài)的初始值是false,所以我們只需要考慮狀態(tài)可能轉(zhuǎn)移為true的情況。即:
f
[
i
]
[
j
]
=
{
f
[
i
?
1
]
[
j
?
1
]
if?
a
[
i
?
1
]
=
=
b
[
j
?
1
]
?
o
r
?
b
[
j
?
1
]
=
′
.
′
f
[
i
?
1
]
[
j
]
?
∣
?
f
[
i
]
[
j
?
1
]
,
if?
b
[
j
?
1
]
?
=
?
′
?
′
?and?(
b
[
j
?
2
]
?
=
=
?
a
[
[
i
?
1
]
?or?
b
[
j
?
2
]
?
=
=
?
′
.
′
)
f[i][j]= \begin{cases} f[i-1][j-1]& \text{if\ $a[i-1]==b[j-1]\ or\ b[j-1]='.'$}\\ \\ f[i-1][j]\ |\ f[i][j-1],& \text{if\ $b[j-1]\ =\ '*'$\ and\ ($b[j-2]\ ==\ a[[i-1]$\ or\ $b[j-2]\ ==\ '.'$)} \end{cases}
f[i][j]=??????f[i?1][j?1]f[i?1][j]?∣?f[i][j?1],?if?a[i?1]==b[j?1]?or?b[j?1]=′.′if?b[j?1]?=?′?′?and?(b[j?2]?==?a[[i?1]?or?b[j?2]?==?′.′)?
以 a = ′ a a a a ′ , b = ′ a ? ′ a='aaaa',b='a*' a=′aaaa′,b=′a?′為例,在求狀態(tài) f [ 4 ] [ 2 ] f[4][2] f[4][2]時,先考慮*前面字符出現(xiàn)一次的情況,即 f [ i ] [ j ? 1 ] f[i][j-1] f[i][j?1]狀態(tài);再考慮*前面字符出現(xiàn) n n n次的情況,此時如果匹配說明 f [ i ? 1 ] [ j ] f[i-1][j] f[i?1][j]也是匹配的,且匹配時*前面字符出現(xiàn)了 n ? 1 n-1 n?1次,再加上 a [ i ? 1 ] = = b [ j ? 2 ] ? o r ? b [ j ? 2 ] = ′ . ′ a[i-1]==b[j-2]\ or\ b[j-2]='.' a[i?1]==b[j?2]?or?b[j?2]=′.′的條件,足以使得 f [ i ] [ j ] f[i][j] f[i][j]匹配。
代碼#include#include#includeusing namespace std;
const int N = 1005;
bool f[N][N];
std::string solution(std::string a, std::string b) {int n = a.size();
int m = b.size();
memset(f,false,sizeof f);
f[0][0] = true;
for(int i = 1; i<= n; i++) {for(int j = 1; j<= m; j++) { if(a[i-1]==b[j-1] || b[j-1]=='.') f[i][j] = f[i-1][j-1];
else if(b[j-1]=='*') { if(b[j-2] == '.' || b[j-2] == a[i-1]) f[i][j] = f[i][j-1] | f[i-1][j];
} else f[i][j] = false;
}
}
if (f[n][m]) return "yes";
else return "no";
}
int main() {std::string a;
std::string b;
getline(std::cin, a);;
getline(std::cin, b);;
std::string result = solution(a, b);
std::cout<
3. 螞蟻家族
題目描述小螞蟻群是一個龐大的群體,在這個螞蟻群中有n只小螞蟻 ,為了保證所有螞蟻在消息傳送的時候都能接收到消息,需要在他們之間建立通信關(guān)系。就是要求小螞蟻都可以通過多只或者直接聯(lián)系到其他人。
已知幾條小螞蟻之間有通信關(guān)系,請問還需要再新建至少多少條關(guān)系?
輸入描述:
第一行輸入整數(shù)n,m;n為小螞蟻總數(shù);m為關(guān)系數(shù)。(1<=n,m<=1000)
以下m行每行m對整數(shù)x,y。(代表x與y有聯(lián)系)
輸出描述:
輸出最少需要新建關(guān)系數(shù)。
輸入樣例:
4 3
1 2
2 3
3 4
輸出樣例:
0
分析這道題數(shù)據(jù)也卡了我不少時間,第一印象是求連通塊的數(shù)量,如果有 r e s res res個連通塊,那么需要新建的關(guān)系數(shù)就是 r e s ? 1 res-1 res?1,然后寫了個dfs求出連通塊的數(shù)量,很快寫完,提交通過六成用例。調(diào)大數(shù)據(jù)范圍依舊只通過六成用例,于是懷疑是否是TLE。想到使用并查集求解更為簡單,遂又寫了個并查集,求集合的個數(shù),寫完提交還是通過了六成用例。后面就暫時做T4了,好在T4比較簡單,很快AC回過頭再看本題。并查集沒有AC說明不是TLE,有可能是螞蟻的編號會出現(xiàn)大于n的情況。
圖論問題一般默認節(jié)點編號在1到n之間,但是本題偏偏就卡了這點,解決辦法也很簡單,并查集建立集合和最后統(tǒng)計集合數(shù)量以大值1000為基準,最后統(tǒng)計新建關(guān)系數(shù)時減去(1000 - n)即可。修改后提交成功AC。
代碼#include#include#include#include#include#includeusing namespace std;
int fa[1005];
int find(int x) {if(x!=fa[x]) fa[x] = find(fa[x]);
return fa[x];
}
int main() {int n;
int m;
std::cin>>n;
std::cin>>m;
int a,b;
for(int i = 1; i<= 1000; i++) fa[i] = i;
for(int i = 0; i< m; i++) {cin>>a>>b;
if(fa[a] !=fa[b]) { fa[find(a)] = find(b);
}
}
sets;
for(int i = 1; i<= 1000; i++) {fa[i] = find(i);
s.insert(fa[i]);
}
int res = s.size() - 1 - (1000 - n);
cout<
4.題目名稱:小股炒股
題目描述已知n天后的股票行情,現(xiàn)在已有的本金是m,
規(guī)定只能入手一次股票和拋售一次股票。
大收益是?
輸入描述:
第一行輸入整數(shù)n,m。(1<=n<=1000,1<=m<=10000)
第二行輸入n個整數(shù)表示某股票單股價格p。(1<=p<=1000)
輸出描述:
輸出小大收益
輸入樣例:
2 4
3 7
輸出樣例:
8
分析股票買賣問題有多種變形,本題之前應(yīng)該沒有刷到過,引入了本金這個變量,難度不大。需要用到DP的思想,但是不需要真正的去DP。設(shè) f [ i ] f[i] f[i]表示在第 i i i天賣出股票獲得的大收益,則題目的解就是 m a x ( f [ i ] ) max(f[i]) max(f[i])。
既然確定了在第 i i i天賣出,那么還需要考慮的就是在哪一天入手,必然要在前面最低價入手才能獲得大的收益,所以需要求出第 i i i天前面的最低價格,平時單調(diào)棧寫習(xí)慣了考試時就寫了個單調(diào)棧維護,其實只需要用一個變量維護當(dāng)前遍歷的最小值 t t t即可,只要前面的最低價 t t t小于本金 m m m,就可以買入,設(shè)第 i i i天的價格是 x x x,則在第 i i i天賣出股票獲得的大收益是 m / t ? ( x ? t ) m / t * (x - t) m/t?(x?t)。這里要注意可能不止買一手,應(yīng)該按照大的手數(shù)去買,才能獲得大的利潤。
代碼#include#include#include#include
#includeusing namespace std;
int solution(int n, int m, std::vector& vec) {int res = 0;
int t = 1e9;
for(auto x : vec) {if (t<= m) { int p = m / t * (x - t);
res = max(res,p);
}
t = min(t,x);
}
return res + m;
}
int main() {int n;
int m;
std::vectorvec;
std::cin>>n;
std::cin>>m;
std::string line_0, token_0;
getline(std::cin >>std::ws,line_0);
std::stringstream tokens_0(line_0);
while(std::getline(tokens_0, token_0, ' ')) {vec.push_back(std::stoi(token_0));
}
int result = solution(n, m,vec);
std::cout<
你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧