1. 程式人生 > >QLU ACM 2018新生賽

QLU ACM 2018新生賽

小蒟蒻也想學大牛們寫一下題解啦~雖然很弱小 但是寫部落格是個好習慣 而且是走向神犇道路的必經之路 所以lets start!!
這次比賽有好幾個題在場上腦子突然短路,不知道為什麼很簡單的題就是想不起來,封榜的時候是第13名,因為沒有做出來題最後銅獎組第一名慘淡收場…剛看到排名和銅獎的時候我的心是哇涼哇涼的 不過後來轉念一想 沒有關係!我才剛剛開始 有好多事情我還沒有經歷過!所以我會以這次比賽為契機 在我鬆懈的時候時刻想著這次的比賽, 積極參加各種比賽 雖然可能不會獲得什麼好的名次 ,但是我也把這些當做我的經歷和鍛鍊 相信這些和相信著我的在我背後的人會推動著我加快我的腳步 走的更遠!(小蒟蒻說這個感覺很慌 不過確實是真心話!!!

問題 M: 簽到題
題目描述
恭喜你發現一道簽到題,請輸出“check in”來解決這道問題。

輸入

輸出
check in

樣例輸入

樣例輸出
check in
第一題是一道簽到題 就不多說了 幸虧我發現這道題a的比較早(笑

#include<bits/stdc++.h>
using namespace std;
int main() {
	cout<<"check in";
}

問題 B: Alice and Bob
命題人:admin

題目描述
Alice and Bob decide to play a game. At the beginning of the game they put n piles of sweets on the table.The number of each pile of sweets may be different. Alice and Bob take away sweets in turn,and always Alice takes sweets first in every games.Each time in their turn they can get only one whole pile of sweets.When there is no sweet left, the game is over. Finally, The man who have the largest number of sweets in hand will win.
Assume that Alice and Bob were very clever.

輸入
The first line is an integer n, which means that there are n pile sweets.
1 <= n <= 100000
Next n integers, the i-th integer means the number of sweets in the i-th pile.
The number of sweets in each pile is less than 10000.

輸出
If Alice wins, output “A”, and if Bob wins, output “B”.
Otherwise output “again”

樣例輸入
樣例輸入1:
3
1 6 7

樣例輸入2:
4
3 3 3 3
題目大意為桌子上有很多堆糖果,每一堆糖果的數量可能不相同,這個Alice姐姐和Bob玩一個遊戲 每個人一次拿一堆,比較最後誰拿到的糖果比較多。
反思:當時沒有注意最後一句她們都很clever 把那一句當做了廢話處理。。。所以沒有進行排序 當天晚上加了一行sort就對了= = 挺難受的也 上程式碼: (下次一定把題目全部吃透!

#include<bits/stdc++.h>
using namespace std;
int b=0,c=0;
unsigned long long int a[200000];
bool cmp(int a,int b) {
	return a>b;
}
int main() {
	long long int  n;
	cin>>n;
	for(int i=1;i<=n;i++) {
	cin>>a[i];
	}
	sort(a+1,a+n+1,cmp);
	for(int i=1;i<=n;i++) {
	if(n==1) {
		if(a[n]<=0)
		cout<<"again";
		else if(a[n]>0)
		cout<<"A";
		return 0;
	}
	else if(n>1&&(i%2!=0))
	b+=a[i];
	else if(n>1&&(i%2==0))
	c+=a[i];
	}
	if(b>c)
	cout<<"A";
	else if(b<c)
	cout<<"B";
	else if(b==c)
	cout<<"again";

} 

問題 C: 黑白黑
命題人:admin

題目描述
黑白黑是一個很經典的遊戲,規則也非常簡單。三個人同時伸出一隻手,手心為白,手背為黑,如果有兩人為黑一人為白,或者兩人為白一人為黑,則單獨伸出手心或者手背的那個人就輸了。
又是一個週末,小A小B小C他們仨個懶蟲又睡到了中午,外賣送到樓下了也不想下樓拿,於是他們決定用這個遊戲來選出一個輸的人去拿外賣。

輸入
三個整數
a b c
(0 <= a,b,c <= 1)
a表示小A
b表示小B
c表示小C
0表示伸出的手背
1表示伸出的手心

輸出
如果有人輸了則輸出他的名字A/B/C(大寫)
平局則輸出"aha"(不含引號)

樣例輸入
樣例輸入1:
0 0 0

樣例輸入2:
1 1 0

樣例輸出
樣例輸出1:
aha

樣例輸出2:
C
這是一道水題 只需要幾個if就ok(小時候玩遊戲配一家的時候用過很多次這個,沒想到現在還能遇到,還有點懷念2333 廢話不多說咯 上程式碼:

#include<bits/stdc++.h>
using namespace std;
int main() {
	int a,b,c;
	cin>>a>>b>>c;
	if((a==0&&b==0&&c==0)||(a==1&&b==1&&c==1))
	cout<<"aha";
	else if((a==1&&b==1&&c==0)||(a==0&&b==0&&c==1))
	cout<<"C";
	else if((a==1&&b==0&&c==1)||(a==0&&b==1&&c==0))
	cout<<"B";
	else if((a==0&&b==1&&c==1)||(a==1&&b==0&&c==0))
	cout<<"A";
} 

問題 E: are you ok?

題目描述
小朋是一家超市的老闆,他經常會來超市檢查,每次都會讓倉庫管理員列出倉庫中剩餘商品的數量。但是倉庫管理員是個非常健忘的人,有時候商品都賣光了也不去進貨,這會讓老闆非常生氣,因為這樣超市賣不出去東西就沒辦法賺錢了。小朋有句口頭禪"are you ok?",如果發現所有商品的庫存都為0的話,就會非常生氣地喊出"are you ok?",大聲地質詢倉庫管理員。
現在你就是倉庫管理員,每次面對小朋的詢問,你都會在電腦系統中對庫存進行查詢,然後列出剩餘商品的清單。(如果所有商品庫存都是0,那你就沒辦法交差了,你的老闆會非常生氣)。

輸入
第一行一個整數n,表示有n種貨物
(2 <= n <= 100)
往下一行有n個字串s1,s2…si…sn 表示系統顯示的第i種貨物的名稱(1<=i<=n)
(字串長度不超過10)
往下一行有n個整數a1,a2…ai…an 表示系統顯示的第i種貨物的庫存(1<=i<=n)
(每種貨物庫存數量 <= 1000)

輸出
如果還有商品(哪怕只有一個),你也可以列出剩餘商品的清單。
否則你就只能挨老闆罵了。

樣例輸入
樣例輸入1:
4
a b c d
0 0 0 0

樣例輸入2:
5
apple egg milk desk light
0 1 2 0 1

樣例輸出
樣例輸出1:
are you ok?

樣例1的說明:
所有的商品都沒庫存, 你的老闆會非常生氣

樣例輸出2:
egg x 1
milk x 2
light x 1
(x前後有空格)

這道題剛看到讓我想起了雷軍那首are you ok hhhh 腦子裡真的出現了那個熟悉而又魔性的旋律(笑哭)
這題只需要使用一下struct結構體 判斷是否為0 輸出即可咯 程式碼:

#include<bits/stdc++.h>
using namespace std;
int f=0;
struct node {
	string name;
	int num;
}a[2000];
int main() {
	int n;
	cin>>n;
	for(int i=0;i<n;i++)
	cin>>a[i].name;
	for(int i=0;i<n;i++)
	cin>>a[i].num;
	for(int i=0;i<n;i++) {
		if(a[i].num!=0) {
			cout<<a[i].name<<" x "<<a[i].num<<"\n";
			f=1;
		}
	}
	if(f==0)
	cout<<"are you ok?";
} 

are you ok? 反正拿了銅獎的我非常的不ok==!
問題 G: 數數
題目描述
小凱今年上一年級了,他只學會了0-9這十個數字,對於兩位以上的數字,小凱自創了一套讀法。
連續出現的x個y,小凱將其讀作“xy”
比如:11 小凱讀作"21" (連續2個1)
21 小凱讀作"1211" (連續1個2 連續1個1)
99 小凱讀作"29" (連續2個9)
310 小凱讀作"131110"(連續1個3 連續1個1 連續1個0)
330111 小凱讀作"231031"(連續2個3 連續1個0 連續3個1)
給定一個由數字組成的字串n(2 <= |n| <= 100),請輸出小凱對n的讀法
|n|表示字串n的長度
保證連續出現同一個數字的次數不會超過9次(因為小凱最多隻能數到9)
比如:2223311111111118(非法,因為數字1連續出現了10次)

輸入
由純數字組成的一行字串

輸出
在小凱的自創規則下這一長串數的讀法

樣例輸入
13145

樣例輸出
1113111415
這道題就是當時在場上腦子抽掉的真實代表 本來很簡單的一道題目讓我想的非常複雜,倒是我在場上做題的時候心態都崩了 直接放棄了這道題 同上 這道題回到宿舍立馬就ac了 (心情複雜.jpg 上程式碼:

#include<bits/stdc++.h>
using namespace std;
int main() {
	string a;
	cin>>a;
	int sum=1;
	for(int i=0;i<a.size();i++) {
		if(a[i]==a[i+1])
		sum++;
		else {
			cout<<sum<<a[i];
			sum=1;
		}
	}
}

問題 H: 神奇老虎機

不知道你有沒有玩過老虎機,現在小明面前有一臺神奇的老虎機,這臺機器有n個滾輪,從左往右數第i個滾輪包含1到a_i的整數(包括1和a_i)。在按下按鈕之後,所有的滾輪都會飛速旋轉,最終停下來,每個滾輪將顯示其中一個整數。這個過程是隨機的。小明有一個有趣的想法,如果將滾輪顯示的數字連線起來看做一長串字串的話,將會有非常多的可能,在這所有的可能中字典序最小的字串是哪個?(只能從左向右讀)

對於字典序的說明:
兩個字串S和T,從前往後比較,如果存在一個位置,在該位置兩個字串的字元不同,則比較小的那個所在的字串字典序更小。
例如: 123的字典序比14的小,因為在第二個位置上2小於4
12345的字典序比9的小
220的字典序比22的大,因為22是220的一個字首

輸入
一個整數t,表示有t組資料(1 <= t <= 100)
每組第一行為一個整數n表示老虎機有n個滾輪
(1 <= n <= 1000)
第二行為n個整數(a_1 a_2 … a_i … a_n )
表示第i個滾輪上的數字範圍(1~a_i)
(1 <= a_i <= 100)

輸出
每組輸入對應一行輸出,輸出字典序最小時老虎機滾輪上顯示的數字
兩個數字之間用空格隔開

樣例輸入
2
4
6 6 6 6
2
2 2

樣例輸出
1 1 1 1
1 1

提示
老虎機上顯示的數都不含前導0
比如:某一塊滾輪包含[1,33],如果它顯示"1"的話,顯示的是"1"而不是"01"

對於樣例2的解釋:
所有情況分別為:“1 1”、“1 2”、“2 1”、“2 2”
其中"1 1"是字典序最小的,所以答案為"1 1"
還有一張圖 由於技術原因就不放出來啦2333 這道題其實也不是很難做 只是需要特判一下最後一位數 即下面程式碼的j==n-1 題目寫的22的字典序比220大 因為要輸出字典序最小的 所以最後一位不能有0 必須是1 於是當最後一項的時候 輸出1和換行即可 程式碼:

#include<bits/stdc++.h>
using namespace std;
int main() {
	int t,n,x;
	cin>>t;
	for(int i=0;i<t;i++) {
		cin>>n;
		for(int j=0;j<n-1;j++) {
			cin>>x;
			if(x<10)
			cout<<1<<" ";
			if(x>=10&&x<100)
			cout<<10<<" ";
			if(x==100)
			cout<<100<<" ";
		}
		cin>>x;
		cout<<1<<" \n";
	} 
}

問題 I: 五環
題目描述
提到五環,我想大家都非常熟悉。“啊五環你比四環多一環~~”
不好意思 跑題了。。。
奧運五環由藍、黃、黑、綠、紅五種顏色的圓環組成。
小迪認為五個圓環分別代表五大洲:
藍色 = 歐洲
黃色 = 亞洲
黑色 = 非洲
綠色 = 大洋州
紅色 = 美洲
對應英文為
Blue = Europe
Yellow = Asia
Black = Africa
Green = Oceania
Red = America

輸入
輸入一行字串
字串為五環的顏色或者五個大洲的名稱

輸出
如果輸入的是顏色則輸出對應的大洲
如果輸入的是大洲則輸出對應的顏色

樣例輸入
Blue

樣例輸出
Europe
這個題我想起來用我剛學的map 還有第二種方法(程式碼2)
程式碼1:

#include<bits/stdc++.h>
using namespace std;
map<string,string>a;
int main() {
	a["Blue"]="Europe";
	a["Yellow"]="Asia";
	a["Black"]="Africa";
	a["Green"]="Oceania";
	a["Red"]="America";
	a["Europe"]="Blue";
	a["Asia"]="Yellow";
	a["Africa"]="Black";
	a["Oceania"]="Green";
	a["America"]="Red";
	string b;
	cin>>b;
	cout<<a[b];
}

如果巧妙運用map的話很多題都是可以輕鬆解決的拉~
程式碼2:

#include<bits/stdc++.h>
using namespace std;
int main() {
	string a;
	cin>>a;
	if(a=="Blue")
	cout<<"Europe";
	else if(a=="Yellow")
	cout<<"Asia";
	else if(a=="Black")
	cout<<"Africa";
	else if(a=="Green")
	cout<<"Oceania";
	else if(a=="Red")
	cout<<"America";
	else if(a=="Europe")
	cout<<"Blue";
	else if(a=="Asia")
	cout<<"Yellow";
	else if(a=="Africa")
	cout<<"Black";
	else if(a=="Oceania")
	cout<<"Green";
	else if(a=="America")
	cout<<"Red";
} 

問題 J: 開掛的小洋
命題人:admin

題目描述
最近小洋迷上了一款名叫打地鼠的遊戲,但是小洋是個遊戲白痴,這麼簡單的遊戲也總是得不到幾分,有一天他發現這款遊戲可以在網路上買到外掛,這款外掛可以提前預知所有地鼠出現的時間,並且他可以開局得到兩把錘子,之前小洋1s只能揮動一次錘子,現在他左右開弓可以同時打中最多兩隻地鼠。每隻地鼠在第i秒出現,在第i+1秒的時候就會消失。也就是說在第i秒小洋只能打到這一秒出現的地鼠,(i-1)秒以及(i+1)秒出現的地鼠他都沒辦法打中。

輸入
一個整數n,表示地鼠的數目
一個整數m,表示此次遊戲時長
接下來n個整數a_1-a_n,表示地鼠會在第a_i秒出現
1 <= a_i <= m
1 <= n <= 1000;
1 <= m <= 100000;
每隻地鼠最多停留一秒

輸出
一個整數,表示小洋最高得分(每打中一隻地鼠得一分)

樣例輸入
樣例輸入1:
4
9
1 1 4 7

樣例輸入2:
6
10
3 3 3 3 9 1

樣例輸出
樣例輸出1:
4

樣例輸出2:
4

提示
對於樣例1的解釋:
第1秒出現兩隻地鼠 左右開弓兩隻全打中得2分
第4秒出現一隻地鼠 打中得1分
第7秒出現一隻地鼠 打中得1分
最終得分4分

對於樣例2的解釋:
第1秒出現一隻地鼠 打中得1分
第3秒出現四隻地鼠 兩把錘子最多打中兩隻 得2分
第9秒出現一隻地鼠 打中得1分
共4分
這題使用了桶的思想 注意桶要開的大一點~ 程式碼:

#include<bits/stdc++.h>
using namespace std;
int a[200000];
int main() {
	int n,m,count=0,b;
	cin>>n>>m;
	for(int i=0;i<n;i++) {
		cin>>b;
		a[b]++;
	}
	for(int i=0;i<200000;i++) {
		if(a[i]!=0) {
			if(a[i]>=2)
			count+=2;
			if(a[i]==1)
			count+=1;
		}
	}
	cout<<count;
}

問題 K: 數字匹配
題目描述
給出兩個元素數量都為n的陣列a和陣列b。對於陣列a中的每個元素,都必須找一個(而且最多一個)陣列b中的元素進行匹配,陣列b中的所有元素也都要被匹配到,也就是說一一匹配。匹配完成後,相互匹配的元素相乘,然後把所有的積相加。
例如:
陣列a:1 5 3
陣列 b:2 3 4
如果a中第一個元素跟b中第三個元素匹配,第二個元素跟b中第二個元素匹配,第三個元素跟b中第一個元素匹配,匹配完後相乘得到 14、53、32,求和得到結果14+53+32=25。
如果a中第一個元素跟b中第二個元素匹配,第二個元素跟b中第三個元素匹配,第三個元素跟b中第一個元素匹配,匹配完後相乘得到 13、54、32,求和得到結果13+54+32=29。

給出n和兩個陣列,分別計算求和的最大結果與最小結果。

輸入
第一行 一個數n,表示兩個陣列元素的個數 1<=n<=1000。
第二行 n個數 表示陣列a的各個元素ai,0<ai<=1000 ai為正整數,(1<=i<=n)。
第三行 n個數 表示陣列b的各個元素bi,0<bi<=1000 bi為正整數,(1<=i<=n)。

輸出
兩個數 分別表示最大結果和最小結果。最大結果和最小結果可以相等。

樣例輸入
3
1 5 3
2 3 4

樣例輸出
31 23
這道題目可以說是我最虧的題目 沒有之一。。。 我做洛谷做慣了 於是就想列舉每一種可能性,然後把結果存到一個數組裡 排序以後輸出第一項和最後一項 可能我的思維在那時候直接江化了 固定思維覺得這樣做不出來就沒法做 忽略了思考的過程 其實只要排序一下 然後再降序拍一下 一相乘就出現了一個最大值和最小值
(當時沒想到真實的腦子抽了 程式碼:

#include<bits/stdc++.h>
using namespace std;
int n,a[2000],b[2000];
bool cmp(int a,int b) {
	return a>b;
}
int main() {
	 int n,maxn=0,minn=0;
	 cin>>n;
	 for(int i=0;i<n;i++)
	 cin>>a[i];
	 for(int i=0;i<n;i++)
	 cin>>b[i];
	 sort(a,a+n);
	 sort(b,b+n);
	 for(int i=0;i<n;i++) {
	 		maxn+=a[i]*b[i];
		 }
	sort(b,b+n,cmp);
	for(int i=0;i<n;i++)
	minn+=a[i]*b[i];
	 cout<<maxn<<" "<<minn;
	
	 }

這道題沒做出來真的是哭暈在廁所啊 當時我那個排名旁邊只有我 沒做出來。。。

這些就是我能寫的所有的題解了…果然蒟蒻就是蒟蒻 不知道有沒有人可以和我產生共鳴 以後我學會了別的題目會再次更新這篇部落格

另外 QLU ACM的大家 一起努力吧!相信我們一定會創造輝煌!!!衝鴨!!!!