合唱团
地牢逃脱
思路: 看了牛客网的toraoh大神的题解,才明白这道题,emmm...不是我一开始想的那个意思。而是起始点到终点的距离都是最短路径,只不过这个终点不定,想知道去哪个终点的最短路径最大,Max(Min),要这个最大的路径值。
所以思路就是,通过BFS搜索去每个点的最短路径,涉及到DP,用dis记录到当前点的最短路径。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include <queue> 3 using namespace std; 4 5 #define INT_MAX 2147483647 6 //定义下INT_MAX, 另外INT_MIN是(-INT_MAX - 1) 7 8 int n, m, k; 9 int direction[51][2]; 10 char field[51][51]; 11 int dis[51][51]; 12 13 struct point 14 { 15 int x, y; 16 point(){} 17 point(int xx, int yy) 18 { 19 x = xx; 20 y = yy; 21 } 22 point goNext(int index) 23 { 24 return point(x + direction[index][0], y + direction[index][1]); 25 } 26 bool check() 27 { 28 if(x >=0 && x < n && y >= 0 && y < m && field[x][y] == '.') 29 return true; 30 else 31 return false; 32 } 33 }; 34 35 int main() 36 { 37 //cout << "Hello world!" << endl; 38 while(cin >> n >> m) 39 { 40 for(int i = 0; i < n; i++) 41 { 42 for(int j = 0; j < m; j++) 43 { 44 cin >> field[i][j]; 45 dis[i][j] = INT_MAX; 46 } 47 } 48 point start; 49 cin >> start.x >> start.y; 50 dis[start.x][start.y] = 0; 51 52 cin >> k; 53 for(int i = 0; i < k; i++) 54 cin >> direction[i][0] >> direction[i][1]; 55 56 queue<point> q; 57 q.push(start); 58 while(!q.empty()) 59 { 60 point current = q.front(); 61 q.pop(); 62 for(int i = 0; i < k; i++) 63 { 64 point next = current.goNext(i); // 下一个点,各个方向都走一步 65 if(next.check()) //下一点可行的话 66 { 67 if(dis[current.x][current.y] + 1 < dis[next.x][next.y]) //当前是更短的路径 68 { 69 dis[next.x][next.y] = dis[current.x][current.y] + 1; 70 q.push(next); // BFS 压栈 71 } 72 } 73 } 74 } 75 int resMax = 0; 76 for(int i = 0; i < n; i++) 77 { 78 for(int j = 0; j < m; j++) 79 { 80 if(field[i][j] == '.' && dis[i][j] > resMax) //还要判断这个点是不是障碍点 81 { 82 resMax = dis[i][j]; 83 } 84 } 85 } 86 87 //判断是否无法离开,无法离开输出-1 88 if(resMax == INT_MAX) 89 resMax = -1; 90 cout << resMax << endl; 91 } 92 return 0; 93 }
小厨房
如果要使用hash_map注意:
#include <ext/hash_map>
using namespace __gnu_cxx;
我在这里使用了set,其实只需要类似hash的功能,再算出数目,即可
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <string> #include <set> using namespace std; int main() { string str; set<string> name; while(cin >> str) { name.insert(str); } cout << name.size() << endl; return 0; }
分田地
分苹果
思路:两种情况是输出“-1”的:
- 当这个数列的和不能被个数整除,这时候平均数不为整;
- 该数列任意一个数与平均数的差不能被2整除时,也就是不能通过移动2个进行补全的时候。
移动的次数,就是那些超过平均数的数目,再除以2,就是次数了。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <vector> using namespace std; int main() { //cout << "Hello world!" << endl; int n; while(cin >> n) { vector<int> num; int sum = 0; for(int i = 0; i < n; i++) { int t; cin >> t; num.push_back(t); sum += t; } int cnt = 0; if(sum % num.size() > 0) { cnt = -1; } else { int avg = sum / num.size(); for(int i = 0; i < num.size(); i++) { if((num[i] - avg) % 2 == 1) { cnt = -1; break; } else if(num[i] > avg) { cnt += (num[i] - avg) / 2; } } } cout << cnt << endl; } return 0; }
星际穿越
藏宝图
思路:便利目标序列,如当前位置为i,在原序列当中找,看str[pos]是否是当前的字符(target[i]),是的话则res++,否的话继续移动下一位(pos++)。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <string> using namespace std; int main() { //cout << "Hello world!" << endl; string str, target; int res; int pos; while(cin >> str >> target) { res = 0; pos = 0; for(int i = 0; i < target.size(); i++) { while(pos < str.size()) { if(target[i] == str[pos]) { pos++; res++; //记录相同个数,找到一个就停止 break; } pos++; } } if(res == target.size()) cout << "Yes" << endl; else cout << "No" << endl; } return 0; }
数列还原
思路:这个顺序对的总数总共包含三个部分:
- 该序列原本的顺序对;
- 新插入序列本身的顺序对;
- 插入序列每个数字加入后的顺序对。
PS:利用全排列函数。next_permutation()包含在头文件<algorithm>里面,可以产生全排列。
int a[]; do{ }while(next_permutation(a,a+n));
下面是AC代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include <iostream> #include <algorithm> using namespace std; int countPair(int a[], int n, int target, int pos) { int res = 0; for(int i = 0; i < n; i++) { if(a[i] > 0) { if((i < pos && a[i] < target) || (i > pos && a[i] > target)) { res++; } } } return res; } int countAllPair(int a[], int n) { int res = 0; for(int i = 0; i < n; i++) { if(a[i] > 0) res += countPair(a, n, a[i], i); } res /= 2; return res; } int countAllSolutions(int has[], int a[], int n, int k) { int res = 0; int miss[10]; int missNum = 0; for(int i = 1; i <= n; i++) { if(has[i] == 0) { miss[missNum++] = i; } } int cntOriginal = countAllPair(a, n); //全排列循环 do{ int cntMiss = countAllPair(miss, missNum); for(int i = 0, j = 0; i < n; i++) { if(a[i] == 0) cntMiss += countPair(a, n, miss[j++], i); } if(cntOriginal + cntMiss == k) res++; //cout << cntOriginal << " " << cntMiss << endl; }while(next_permutation(miss,miss + missNum)); return res; } int main() { //cout << "Hello world!" << endl; int n, k; int a[100]; while(cin >> n >> k) { int has[101] = {0}; for(int i = 0; i < n; i++) { cin >> a[i]; has[a[i]] = 1; } cout << countAllSolutions(has, a, n, k) << endl; } return 0; }