AtCoder Beginner Contest 151 題解報告


總的來說,這次的題目比較水,然而菜菜的我並沒有把所有題目都做完, 話不多說,直接來干貨: #A:Next Alphabet# 題目鏈接:https://atcoder.jp/contests/abc151/tasks/abc151_a

題目描述:Given is a lowercase English letter C that is not z. Print the letter that follows C
        in alphabetical order.
大致解讀:給你一個小寫字母,輸出這個小寫字母的后一個字母(所有樣例中不會有 z 字母的出現)
樣例:
input :a
output:b

AC代碼:

#include<iostream>
#include<cstring>
#include<string> 
using namespace std;
int main(void) {
	string str;
	cin >> str;
	printf("%c\n",str[0] + 1);
	return 0;
}

#B: Achieve the Goal# 題目鏈接:https://atcoder.jp/contests/abc151/tasks/abc151_b

題目描述:Takahashi is taking exams on N subjects. The score on each subject will be an integer between 
        0 and K(inclusive).He has already taken exams on N−1 subjects and scored A i points on the i-th 
        subject.His goal is to achieve the average score of M points or above on the N subjects.  Print 
        the minimum number of points Takahashi needs on the final subject to achieve his goal.   If the 
        goal is unachievable, print -1 instead.
大致解讀:題目中會給你 N - 1 個數,然后需要找滿足某種條件的第 N 個數,問是否存在這樣的一個數,如果存在,輸出這個數。
         不存在,則輸出 '-1'。
         尋找的這個數的條件:
         1、范圍必須在0 ~ k(包括0 and k)
         2、與前 N - 1個數的平均值在 M 及 M 之上 (英文的重要性,hh)
樣例:
input  :5 10 7
        8 10 3 6
output :8
析題有解:初看這道題,感覺是數論,(哈哈,實際上是自己見的東西太少了,根本不是數論),然后直接就去做后面的題了,A了第三題
         之后,看榜單發現大家都做了這道題,這么多人能做出來,我也一定可以,然后再去讀題,發現竟然如此水,主要還是自己
         英文不好,題沒讀懂,哈哈哈。

AC代碼:

#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 105;
int n,k,m,sum;
float aver;
int main(void) {
	cin >> n >> k >> m;
	sum = 0;
	for(int i = 1; i <= n - 1; i ++) {
		int num;
		cin >> num;
		sum += num;
	}
	for(int j = 0; j <= k; j ++) {
	    aver = (sum + j) * 1.0 / n;
	    if(aver >= m) {
	    	cout << j << endl;
	    	return 0;
		}
	}
	cout << "-1" << endl;
	return 0;
}

#C:Welcome to AtCoder# 題目鏈接:https://atcoder.jp/contests/abc151/tasks/abc151_c

題目描述:Takahashi participated in a contest on AtCoder.The contest had N problems.
        Takahashi made M submissions during the contest.The i-th submission was made 
        for the pi-th problem and received the verdict Si (AC or WA).  The number of
        Takahashi's   correct  answers is the number of problems on which he received
        an AC once or more.The number of Takahashi's penalties is the sum of the following 
        count for the problems on which he received an AC once or more: the number of WAs 
        received before receiving an AC for the first time on that problem.
        Find the numbers of Takahashi's correct answers and penalties.
大致解讀:
      與我們平常在網站上做題目交題時評測機類似,根據 AC 和 WA 來判斷 A 了幾道題,在 A 完給出的所以
      題之前我們 WA 掉了幾次,最后輸出 AC 題目結果和 我們所有 WA 了的次數。
      注意:一道題目 AC 過后之后 WA 的結果就不再被累計(常識的東西就不再一一介紹了,可以自己找OJ測試一下)
樣例   :
input : 2 5
        1 WA
        1 AC
        2 WA
        2 AC
        2 WA
outout: 2 2

AC代碼:

    #include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<map>
using namespace std;
const int maxn = 1e5 + 10;
int a[maxn];
map<int,int>maps;
map<int,int>::iterator it;
int n,m;
int ac = 0,wa = 0;
int main(void) {
	void solve();
	cin >> n >> m;
	ac = wa = 0;
	solve();
	return 0;
}
void solve() {
	if(m == 0) {
		cout << 0 << " " << 0 << endl;
		return ;
	}
	int num;
	string vis;
	for(int i = 1; i <= m; i ++) {
		cin >> num >> vis;
		if(maps[num] == -1) continue;
		if(vis == "AC") {
			wa += maps[num];
			ac += 1;
			maps[num] = -1;
			continue;
		}
		maps[num] ++;
	}
	maps.clear();
	cout << ac << " " << wa << endl;
	return ;
}

#D:Maze Master# 題目鏈接:https://atcoder.jp/contests/abc151/tasks/abc151_d

題目描述:Takahashi has a maze, which is a grid of H × W squares with H horizontal rows and 
        W vertical columns.The square at the i-th row from the top and the j-th column is 
        a "wall" square if Sij is #, and a "road" square if Sij is ..
        From a road square, you can move to a horizontally or vertically adjacent road square.
        You cannot move out of the maze, move to a wall square, or move diagonally.Takahashi will 
        choose a starting square and a goal square, which can be any road squares, and give the maze to Aoki. 
        Aoki will then travel from the starting square to the goal square, in the minimum number of moves required.
        In this situation, find the maximum possible number of moves Aoki has to make.
大致解讀:有一個 H * W 的迷宮,自己任意定義一個起點和終點,找到一個最遠的距離且是存在一條最短路徑,輸出這條路的最短步數。
數值范圍:1≤H,W≤20
樣例:
input :3 3
       ...
       ...
       ...
output: 4
input:3 5
      ...#.
      .#.#.
      .#...
output: 10
析題有解:這道題有一個需要特別注意的地方,就是數值范圍,最大是 20 ,這么小的范圍,當然暴力來一發咯,哈哈。
        起點和終點都沒有給我們,而我們又要求一個最大值,只能逐個遍歷每一個合適的點,尋找滿足這個點的合
        適路徑的最少步數。
考察算法:BFS經典走迷宮

AC代碼:

方法一(結構體的運用 + 標記):
#include<iostream>
#include<algorithm>
#include<cstring>
#include<string>
#include<string.h>
#include<limits.h>
#include<vector>
#include<deque>
#include<queue>
#include<stack>
#include<set>
#include<map>
using namespace std;
const int maxn = 25;
char str[maxn][maxn];
int vis[maxn][maxn];
struct node {                                           // 結構體將其信息綁定到一起
	int x,y,step;
} dot[maxn];
int dir[][2] = {{1,0},{-1,0},{0,1},{0,-1}};             // 方向
int n,m;
int ans = 0,res = 0;                                
int main(void) {
	int BFS(int start_x,int start_y);
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= n; i ++) {
		for(int j = 0; j <= m; j ++) {         // 有換行字符,所以從 0 開始
 			scanf("%c",&str[i][j]);
		}
	}
	ans = 0;
	for(int i = 1; i <= n; i ++) {
		for(int j = 1; j <= m; j ++) {
			if(str[i][j] == '#') continue;
			res = BFS(i,j);
			ans = max(ans,res);
		}
	}
	cout << ans << endl;
	return 0;
}

bool Check(int x,int y) {
	if(x < 1 || y < 1 || x > n || y > m) return false;
	if(vis[x][y] || str[x][y] == '#') return false;
	if(str[x][y] == '.') return true;
}

int BFS(int start_x,int start_y) {
	memset(vis,0,sizeof(vis));                                // 復原
	int count = 0;                                               
	queue<node>queues;
	while(!queues.empty()) queues.pop();
	node first,second;
	first.x = start_x,first.y = start_y,first.step = 0;
	queues.push(first);
	vis[start_x][start_y] = 1;
	while(!queues.empty()) {
		first = queues.front();
		queues.pop();
		count = max(count,first.step);                   // 每次進行比較得到最大的值
		for(int i = 0; i < 4; i ++) {
			second.x = first.x + dir[i][0];
			second.y = first.y + dir[i][1];
			if(!Check(second.x,second.y)) continue;  // 注意這里用 !  (這里卡了好久,一定要記得自己寫的Check函數返回的是什么)
			second.step = first.step + 1;
			queues.push(second);
			vis[second.x][second.y] = 1;
		}
	}
	return count;
}

方法二(pair的運用,參考大佬寫的,感覺相對於結構體來說,更好用一點,再次特地感謝那位無名大佬):

大致思路類似:

#include<iostream>
#include<algorithm>
#include<cstring>
#include<string.h>
#include<limits.h>
#include<string>
#include<vector>
#include<deque>
#include<queue>
#include<stack>
#include<map>
#include<set>

#define P pair<int,int>
#define x first
#define y second

using namespace std;
const int maxn = 25;
char str[maxn][maxn];
int num[maxn][maxn];
int dir[][2] = {{1,0},{-1,0},{0,1},{0,-1}};
int n,m,ans,res;

queue<P>Q;

int main(void) {
	int BFS(int start_x,int start_y);
	scanf("%d%d",&n,&m);
	for(int i = 1; i <= n; i ++) {
		for(int j = 0; j <= m; j ++) {
			scanf("%c",&str[i][j]);
		}
	}
	ans = 0,res = 0;
	for(int i = 1; i <= n; i ++) {
		for(int j = 1; j <= m; j ++ ) {
			if(str[i][j] == '#') continue;
			res = BFS(i,j);
			ans = max(ans,res);
		}
	}
	cout << ans << endl;
	return 0;
}

bool Check(int x,int y) {
	if(x < 1 || y < 1 || x > n || y > m) return false;
	if(str[x][y] == '#' || num[x][y]) return false;
	if(str[x][y] == '.') return true;
}

int BFS(int start_x,int start_y) {
	P a,b;
	int count = 0;
	memset(num,0,sizeof(num));
	while(!Q.empty()) Q.pop();
	a.x = start_x,a.y = start_y;
	Q.push(a);
	while(!Q.empty()) {
		a = Q.front();
		Q.pop();
		count = max(count,num[a.x][a.y]);
		int v = num[a.x][a.y];
		for(int i = 0; i < 4; i ++) {
			b.x = a.x + dir[i][0];
			b.y = a.y + dir[i][1];
			if(!Check(b.x,b.y)) continue;
			if(b.x != start_x || b.y != start_y) { // 要保證不會回到最初的點,因為這種方法我們沒有進行標記 
				num[b.x][b.y] = v + 1;
				Q.push(b);
			}
			/*
			   如果不加特殊判斷的話就會出現錯誤,下面是特殊樣例:
			   2 2
			   #.
			   #. 
			*/
			
		}
	}
	return count;
}
知識總結:
1、復習了 map 容器的運用,更加熟練。
2、對迷宮問題有了更深一步的了解,同時對 BFS 也算回顧復習了一下(Check語句一定要認真,弄清楚返回的是什么)
3、pair<int,int> 的應用,相對於結構體來說,這個的應用更方便一點。
#賽后小結:#
1、認真讀題,認真讀題,一定要真正讀題,有可能一個小小的細節就會導致大錯誤。
2、大膽一點,有想法就要嘗試一下。
3、堅持到比賽最后一秒,不要因為時間快到了就不去想了,也不要因為別人都做出來了而不再去嘗試。

···

能力有限,如有寫的不到位的地方,望路過的朋友留下您的建議,在下會細心改正,萬分感謝。

后續更新 ing............

···


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM