今日訓練 三題 搜索
C. King‘s Path
The black king is standing on a chess field consisting of 109 rows and 109 columns. We will consider the rows of the field numbered with integers from 1 to 109 from top to bottom. The columns are similarly numbered with integers from 1 to 109 from left to right. We will denote a cell of the field that is located in the i
You know that some squares of the given chess field are allowed. All allowed cells of the chess field are given as n segments. Each segment is described by three integers ri, ai, bi (ai ≤ bi), denoting that cells in columns from number a
Your task is to find the minimum number of moves the king needs to get from square (x0, y0) to square (x1, y1), provided that he only moves along the allowed cells. In other words, the king can be located only on allowed cells on his way.
Let us remind you that a chess king can move to any of the neighboring cells in one move. Two cells of a chess field are considered neighboring if they share at least one point.
InputThe first line contains four space-separated integers x0, y0, x1, y1 (1 ≤ x0, y0, x1, y1 ≤ 109), denoting the initial and the final positions of the king.
The second line contains a single integer n (1 ≤ n ≤ 105), denoting the number of segments of allowed cells. Next n lines contain the descriptions of these segments. The i-th line contains three space-separated integers ri, ai, bi (1 ≤ ri, ai, bi ≤ 109, ai ≤ bi), denoting that cells in columns from number ai to number bi inclusive in the ri-th row are allowed. Note that the segments of the allowed cells can intersect and embed arbitrarily.
It is guaranteed that the king‘s initial and final position are allowed cells. It is guaranteed that the king‘s initial and the final positions do not coincide. It is guaranteed that the total length of all given segments doesn‘t exceed 105.
OutputIf there is no path between the initial and final position along allowed cells, print -1.
Otherwise print a single integer — the minimum number of moves the king needs to get from the initial position to the final one.
Examples input Copy5 7 6 11output Copy
3
5 3 8
6 7 11
5 2 5
4input Copy
3 4 3 10output Copy
3
3 1 4
4 5 9
3 10 10
6input Copy
1 1 2 10output Copy
2
1 1 3
2 6 10
-1
這個也是一個bfs,也是一個模板題,但是因為這個圖有1e9*1e9所以開數組沒法存下
這個就是要處理的重點,我不會。。。然後上網查了,用pair和map
具體看下面的代碼
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <map> #include <iostream> #include <vector> #include <queue> #define inf 0x3f3f3f3f using namespace std; const int maxn = 1e6 + 100; typedef long long ll; map<pair<int,int>, int>mp; queue < pair<int, int>>que; int sx, sy, gx, gy; int dx[8] = { 0,0,1,-1,1,1,-1,-1 }; int dy[8] = { 1,-1,0,0,1,-1,-1,1 }; int main() { cin >> sx >> sy >> gx >> gy; int n; cin >> n; for(int i=0;i<n;i++) { int r, a, b; cin >> r >> a >> b; for(int j=a;j<=b;j++) { mp[make_pair(r, j)] = -1; } } mp[make_pair(sx, sy)] = 0; que.push(make_pair(sx, sy)); while(!que.empty()) { int x = que.front().first; int y = que.front().second; que.pop(); if (x == gx && y == gy) break; for(int i=0;i<8;i++) { int tx = x + dx[i]; int ty = y + dy[i]; if (tx > 1e9 || ty > 1e9 || tx < 1 || ty < 1) continue; if(mp[make_pair(tx,ty)]<0) { mp[make_pair(tx, ty)] = mp[make_pair(x, y)] + 1; que.push(make_pair(tx, ty)); } } } printf("%d\n", mp[make_pair(gx, gy)]); return 0; }
C. Restore Graph
Valera had an undirected connected graph without self-loops and multiple edges consisting of n vertices. The graph had an interesting property: there were at most k edges adjacent to each of its vertices. For convenience, we will assume that the graph vertices were indexed by integers from 1 to n.
One day Valera counted the shortest distances from one of the graph vertices to all other ones and wrote them out in array d. Thus, element d[i] of the array shows the shortest distance from the vertex Valera chose to vertex number i.
Then something irreparable terrible happened. Valera lost the initial graph. However, he still has the array d. Help him restore the lost graph.
InputThe first line contains two space-separated integers n and k (1 ≤ k < n ≤ 105). Number n shows the number of vertices in the original graph. Number k shows that at most k edges were adjacent to each vertex in the original graph.
The second line contains space-separated integers d[1], d[2], ..., d[n] (0 ≤ d[i] < n). Number d[i] shows the shortest distance from the vertex Valera chose to the vertex number i.
OutputIf Valera made a mistake in his notes and the required graph doesn‘t exist, print in the first line number -1. Otherwise, in the first line print integer m (0 ≤ m ≤ 106) — the number of edges in the found graph.
In each of the next m lines print two space-separated integers ai and bi (1 ≤ ai, bi ≤ n; ai ≠ bi), denoting the edge that connects vertices with numbers ai and bi. The graph shouldn‘t contain self-loops and multiple edges. If there are multiple possible answers, print any of them.
Examples input Copy3 2output Copy
0 1 1
3input Copy
1 2
1 3
3 2
4 2output Copy
2 0 1 3
3input Copy
1 3
1 4
2 3
3 1output Copy
0 0 0
-1
這個我覺得是樹的問題,可以用dfs寫,但是我不太會,所以就沒有dfs
然後你觀察之後你就會發現,這個d值代表的就是這棵的深度。
所以你就直接建圖就好了,
除了第一個根節點只有一個之外,每一個深度的節點數都小於等於上一個深度的節點數,這個就可以判斷是不是-1,同時可以求出邊的數量,
然後就一層一層的開始建圖
我的寫法有點小復雜,其實可以更簡單
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <map> #include <iostream> #include <vector> #include <queue> #define inf 0x3f3f3f3f using namespace std; const int maxn = 1e5 + 100; typedef long long ll; struct node { int id, d, num; node(int id=0,int d=0):id(id),d(d){} }; vector<node>vec[maxn]; int main() { int n, k,mx=0; cin >> n >> k; for(int i=1;i<=n;i++) { int x; cin >> x; vec[x].push_back(i); mx = max(mx, x); } if(vec[0].size()!=1) { printf("-1\n"); return 0; } int ans = 0; for(int i=1;i<=mx;i++) { ans += vec[i].size(); if (i == 1 && vec[i].size() <= vec[i - 1].size() * 1ll * k) continue; if(vec[i].size()>vec[i-1].size()*1ll*(k-1)) { printf("-1\n"); return 0; } } printf("%d\n", ans); for(int i=1;i<=mx;i++) { int num = 0,cnt=0; int l = vec[i].size(); int len = vec[i-1].size(); while(num<len&&cnt<l) { int tot = 0; while ((tot < k-1||(i==1&&tot<k))&&cnt < l) { //printf("i=%d num=%d cnt=%d\n", i,num, cnt); printf("%d %d\n", vec[i - 1][num].id, vec[i][cnt].id); cnt++; tot++; } num++; //printf("num=%d cnt=%d\n", num, cnt); } } return 0; }
B. Phillip and Trains
The mobile application store has a new game called "Subway Roller".
The protagonist of the game Philip is located in one end of the tunnel and wants to get out of the other one. The tunnel is a rectangular field consisting of three rows and n columns. At the beginning of the game the hero is in some cell of the leftmost column. Some number of trains rides towards the hero. Each train consists of two or more neighbouring cells in some row of the field.
All trains are moving from right to left at a speed of two cells per second, and the hero runs from left to right at the speed of one cell per second. For simplicity, the game is implemented so that the hero and the trains move in turns. First, the hero moves one cell to the right, then one square up or down, or stays idle. Then all the trains move twice simultaneously one cell to the left. Thus, in one move, Philip definitely makes a move to the right and can move up or down. If at any point, Philip is in the same cell with a train, he loses. If the train reaches the left column, it continues to move as before, leaving the tunnel.
Your task is to answer the question whether there is a sequence of movements of Philip, such that he would be able to get to the rightmost column.
Each test contains from one to ten sets of the input data. The first line of the test contains a single integer t (1 ≤ t ≤ 10 for pretests and tests or t = 1 for hacks; see the Notes section for details) — the number of sets.
Then follows the description of t sets of the input data.
The first line of the description of each set contains two integers n, k (2 ≤ n ≤ 100, 1 ≤ k ≤ 26) — the number of columns on the field and the number of trains. Each of the following three lines contains the sequence of n character, representing the row of the field where the game is on. Philip‘s initial position is marked as ‘s‘, he is in the leftmost column. Each of the k trains is marked by some sequence of identical uppercase letters of the English alphabet, located in one line. Distinct trains are represented by distinct letters. Character ‘.‘ represents an empty cell, that is, the cell that doesn‘t contain either Philip or the trains.
OutputFor each set of the input data print on a single line word YES, if it is possible to win the game and word NO otherwise.
Examples input Copy2output Copy
16 4
...AAAAA........
s.BBB......CCCCC
........DDDDD...
16 4
...AAAAA........
s.BBB....CCCCC..
.......DDDDD....
YESinput Copy
NO
2output Copy
10 4
s.ZZ......
.....AAABB
.YYYYYY...
10 4
s.ZZ......
....AAAABB
.YYYYYY...
YESNote
NO
In the first set of the input of the first sample Philip must first go forward and go down to the third row of the field, then go only forward, then go forward and climb to the second row, go forward again and go up to the first row. After that way no train blocks Philip‘s path, so he can go straight to the end of the tunnel.
Note that in this problem the challenges are restricted to tests that contain only one testset.
這個題目就是一個bfs的板子,你只要把車向左運動轉化成人向右走就好了
還有就是註意人怎麽走的,先向右走一格,然後 向上走,向下走,或者不動。
這個你不要以為一直向右走就不要vis標記,如果你沒有標記,你會哭的(會爆內存
#include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> #include <map> #include <iostream> #include <vector> #include <queue> #define inf 0x3f3f3f3f using namespace std; const int maxn = 150; typedef long long ll; struct node { int x, y; node(int x=0,int y=0):x(x),y(y){} }; int m, vis[maxn][maxn],sx,sy; char s[10][maxn]; int dx[3] = { 0,1,-1 }; int dy[3] = { 1,1,1 }; int bfs() { queue<node>que; que.push(node(sx, sy)); vis[sx][sy] = 1; while(!que.empty()) { node e = que.front(); que.pop(); //printf("%d %d\n", e.x + 1, e.y); if (s[e.x][e.y+1] != ‘.‘) continue; for(int i=0;i<3;i++) { int tx = e.x + dx[i]; int ty = e.y + dy[i]; if (vis[tx][ty]) continue; if (tx<1 || ty<1 || tx>3) continue; if (s[tx][ty] != ‘.‘) continue; if (ty >= m) return 1; if (s[tx][ty + 1] != ‘.‘) continue; if (ty + 1 >= m) return 1; if (s[tx][ty + 2] != ‘.‘) continue; if (ty + 2 >= m) return 1; //printf("tx=%d ty=%d\n", tx, ty); vis[e.x][e.y+1] = 1; vis[tx][ty] = 1; vis[tx][ty + 1] = 1; vis[tx][ty + 2] = 1; que.push(node(tx, ty + 2)); } } return 0; } int main() { int t,k; cin >> t; while(t--) { cin >> m>>k; for(int i=1;i<=3;i++) { cin >> s[i] + 1; for(int j=1;j<=m;j++) { if (s[i][j] == ‘s‘) sx = i, sy = j; } } memset(vis, 0, sizeof(vis)); int f=bfs(); if (f) printf("YES\n"); else printf("NO\n"); } return 0; }
今日訓練 三題 搜索