## 弱雞的第三次線上賽總結(TKK18no.6)(WIP)
一些閒話
這次隔了這麼久才更這一次線上賽,其實中間有一丟丟原因,我先在這裡甩個鍋。其一是上次線上賽沒參加(不要和我提轉普通練習),去參加了志願者活動(心中有黨);其二是其實這次線上賽也有兩題沒過,琢磨了半天還是runtime或者memory limit。但想了想還是先把這次的WIP發出來,接受指導與建議。
第一題:字串替換
把字串s中的前m個字元c替換成字串d。
輸入一個正整數n,表示測試案例的數量。
每組案例由一個字串s,一個正整數m,一個字元c,一個字串d組成。(保證s裡至少會有m個c字元)
輸出
針對每組案例,輸出一個字串,表示根據描述變化後的字串。
每組案例輸出完都要換行。
沒什麼好說的,找出來,換一下,輸出來。
#include <iostream> #include<string> using namespace std; int main() { int m, n,i; string a, b; char c; cin >> n; while (n--) { cin >> a >> m >> c >> b; for (i = 0; i < a.length(); i++) { if (a[i] == c&&m!=0) { cout << b; m--; } else cout << a[i]; } cout << endl; } }
第二題:大柱的乘法
大柱規定了一種特別的乘法:當兩個數相乘時,列豎式計算;如果位數不同,則通過高位補0的方式對齊;運算時,每個數位分開計算,相同數位上下兩個數字相乘,取乘積的個位數作為該數位的值。例如:
這道題就按照題意實現即可,依位數補完再相乘即可。
#include<iostream> #include<string> #include<cmath> #include<algorithm> using namespace std; int main() { int m, n, k; string a, b,t; char c; cin >> n; while (n--) { cin >> a >> b; t = ""; int j = b.length() - 1; for (int i = a.length() - 1; i >= 0 ; i--) { t += char((((a[i] - '0')*(b[j] - '0')) % 10)+'0'); j--; if(j<0)break; } int k = 0; for (int i = t.length() - 1; i >= 0; i--) { if (t[i] != '0'&&k==0) { k = 1; cout << t[i]; } else if(k==1) cout << t[i]; } if (k == 0) cout << 0; cout << endl; } return 0; }
第三題:誰是臥底
曹操因為“雞肋”口令殺了楊修之後,覺得拿某個名詞當口令太容易讓文官們胡思亂想,所以使用了一個整數當口令,見面時喊這個整數來表明是自己人而不是敵方間諜。然而後來又遇到了個問題,士兵們記性不好,無法準確記住這個整數,於是曹操規定,只要喊的數字能和口令相差10之內(包括10)都算對,這下子所有士兵都能喊出正確範圍內的口令。有一天來了個蜀國的間諜混入了士兵中,曹操為了能分清總共m名士兵中,究竟誰是間諜,就讓他們各自在紙上寫下口令,同時交上來。假設魏國的士兵都各自寫出了正確範圍內的一個口令,而唯一一個蜀國的間諜是亂寫的。這時曹操的頭風病犯了,自己不記得口令是多少了,而且曹操生性多疑,不相信別人告訴他的口令。
問:曹操是否有可能根據士兵們交上來的口令,就能明確斷定出誰是間諜?
輸入
一個正整數n,表示n組案例。
每組案例先是一個正整數m(2<=m<=10000),表示連同間諜在內一共有m名士兵。然後是m個整數,分別表示第1、2、…、m名士兵寫的口令。案例保證最多隻會有一名間諜。
輸出
針對每組案例,如果無法區分誰是間諜,則輸出Cannot;如果能找出間諜,則輸出間諜是第幾個士兵(士兵編號從1到m)。
每組案例輸出完都要換行。
關於這道題,其實我是有些疑惑的,比如5,20,20,20,35是不是Cannot,但後來聽說好像不需要考慮這種可能。所以就是所有的數快排一下,然後要麼最大要麼最小,判斷哪個是臥底。
#include <iostream>
#include<algorithm>
#include<cmath>
using namespace std;
struct s
{
int id, num;
};
int main()
{
int n;
cin >> n;
while (n--)
{
int m,k;
cin >> m;
if (m > 2)
{
s x[m];
for (int i = 0; i < m; i++)
{
x[i].id = i + 1;
cin >> x[i].num;
}
for (int i = 1; i < m; i++)
{
for (int j = 0; j < i; j++)
{
if (x[j].num>x[i].num)
swap(x[i], x[j]);
}
}
if (x[m - 1].num - x[0].num <= 20)
cout << "Cannot";
else
{
if (x[m - 1].num - 20 > x[1].num)
cout << x[m-1].id;
else cout << x [0].id;
}
cout << endl;
}
else
{
while (m--)
cin >> k;
cout << "Cannot" << endl;
}
}
return 0;
}
第四題:貨郎擔
星星用扁擔挑了一攤貨去趕集。貨物一共有10件,每件貨物都有一定的重量。扁擔的兩邊各吊著一個筐,筐中可以裝任意多件貨物。星星希望兩個筐中的貨物重量差距儘可能小,以方便挑擔時保持平衡。問該重量差距最小是多少?
這道題應該是揹包的變形,同時因為案例比較小也可以用dfs做,但是不知道為什麼,我就是re轉mle。
丟臉,不發程式碼了。
第五題:字串出現次數
看看a字串裡出現了多少次b字串,規定如果多個b字串在a中的位置出現重疊,則都不計入次數。
例如abababa裡計算出現了多少次的aba時,由於所有的aba字串都存在與別的aba字串位置重疊,所以一共出現0次。
這個題也比較基礎,就是找出來b字串後把他的位置存好,和後一個比較是否小於b的長度。
#include<iostream>
#include<string>
using namespace std;
int main()
{
int n;
cin>>n;
while(n--)
{
string a,b;
cin>>a>>b;
int B=b.length();
int r=-B-1;
int sum=0;
for(int i=0;i<a.length();i++)
{
if(a.substr(i,B)==b)
{
if(sum==1&&i-r<B)
{
sum--;
}
if(i-r>=B)
{
sum=sum+1;
}
r=i;
}
}
cout<<sum<<endl;
}
}
第六題:三英戰大柱
有m個勇敢的學弟想要線下賽組隊挑戰大柱,規則上至多隻允許3個學弟組隊。黃大佬作為學弟的精神領袖,想要暗地幫助學弟組隊,以達到最好的效果,即把所有題目都做出來。這m個學弟分別把所有題目的解題思路告訴了黃大佬,黃大佬記下了每個學弟按照解題思路是否可以做對每道題。然後黃大佬根據掌握的情況,想看看是否能夠選出3個學弟,使得每道題都至少有其中一個學弟能做對。
輸入
一個正整數n,表示有n組案例。每組案例先是兩個正整數m和p,分別表示學弟的數量和題目的數量(3<=m<=10, p<=500000)然後是m行資料,每行資料由p個字元組成,其中第i行第j個表示第i個學弟第j題做對還是做錯了。字元含義如下:A——正確,W——答案不對,T——超時,M——超記憶體,不會有除此之外的其它字元,每個字元之間有個空格,只有A表示做對。
輸出
針對每組案例,如果能夠選出3個學弟,使得每道題都至少有其中一個學弟能做對,那麼輸出Yes,否則輸出No。每組案例輸出完都要換行。
這題我也還沒a出來,也是可以實現但是mle,但這題還是貼一下程式碼,以供參考,因為案例比較小,所以我直接三重迴圈了。
#include<iostream>
using namespace std;
int main()
{
int n;
cin>>n;
while(n--)
{
int m, p;
cin>>m>>p;
int x[m][p];
for(int i=0;i<m;i++)
{
for(int j=0;j<p;j++)
{
char a;
cin>>a;
if(a=='A')x[i][j]=1;
else x[i][j]=0;
}
}
int sum=0;
for(int i=0;i<m;i++)
{
for(int j=0;j<m&&j!=i;j++)
{
for(int k=0;k<m&&k!=i&&k!=j;k++)
{
int b=1;
for(int c=0;c<p;c++)
{
if(x[i][c]+x[j][c]+x[k][c]==0)
{
b=0;
}
}
if(b==1)sum=1;
}
}
}
if(sum)cout<<"Yes"<<endl;
else cout<<"No"<<endl;
}
}
這時候還是runtime,因為我用的dev所以直接定義x[m][p],雖然這樣肯定不規範。
#include<iostream>
using namespace std;
int main()
{
int n;
cin >> n;
while (n--)
{
int m, p;
m = 10; p = 500000;
bool **x = new bool*[m];
for (int i = 0; i < m; i++)
{
x[i] = new bool[p];
}
for (int i = 0; i<m; i++)
{
for (int j = 0; j<p; j++)
{
char a;
a = 'A';
if (a == 'A')x[i][j] = 1;
else x[i][j] = 0;
}
}
bool sum = 0;
for (int i = 0; i<m; i++)
{
for (int j = 0; j<m&&j != i; j++)
{
for (int k = 0; k<m&&k != i&&k != j; k++)
{
bool b = 1;
for (int c = 0; c<p; c++)
{
if (x[i][c] + x[j][c] + x[k][c] == 0)
{
b = 0;
}
}
if (b == 1)sum = 1;
}
}
}
if (sum)cout << "Yes" << endl;
else cout << "No" << endl;
for (int i = 0; i < m; i++)
{
delete[] x[i];
}
delete x;
}
return 0;
}
但是當我這樣new了一個二維陣列然後delete掉的時候,又變成了mle,就很難受。
還有一點閒話
就是因為這次線上賽是這學期最後一次,所以可能下學期再更,也有可能寒假隨緣更。希望發現我的bug的大佬(如果有空的話)可以評論或者+q309894263討論!(第四題用vector炸了)