标签:遍历 contest bfs names 步骤 超时 mem clu memset
Solution:
输出\(ad-bc\)
#include <iostream>
using namespace std;
int main()
{
int a, b, c, d;
cin >> a >> b >> c >> d;
cout << a * d - b * c << endl;
return 0;
}
Solution:
遍历整个字符串,遇到‘x‘减1,遇到’o‘加1,注意中间值不能小于0.
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 211111;
int n, x;
char str[maxn];
int main()
{
cin >> n >> x;
cin >> str;
for(int i = 0; i < n; ++i) {
if(str[i] == ‘o‘) x++;
else x = max(0, x - 1);
}
cout << x << endl;
return 0;
}
Solution:
分析一个位置可以一次到达的点可知有两种情况:
考虑这两种到达方式可知:
#include <iostream>
#include <cmath>
#include <algorithm>
using namespace std;
int main()
{
long long a, b, c, d;
cin >> a >> b >> c >> d;
if(a == c && b == d) {
cout << 0 << endl;
return 0;
}
if(a + b == c + d || a - b == c - d || abs(a - c) + abs(b - d) <= 3) cout << 1 << endl;
else {
bool fl = false;
for(int i = -3; i <= 3; ++i) {
for(int j = -3; j <= 3; ++j) {
if(i + j > 3) continue;
int x = a + i;
int y = b + j;
if(x + y == c + d || x - y == c - d || abs(x - c) + abs(y - d) <= 3) fl = true;
}
}
if((c + d - b + a) % 2 == 0 && (c + d + b - a) % 2 == 0) fl = true;
if((b + a - d + c) % 2 == 0 && (b + a + d - c) % 2 == 0) fl = true;
cout << (fl ? 2 : 3) << endl;
}
return 0;
}
Solution:
dfs搜索每种种情况的所需步数,加入记忆化搜索优化(否则超时)
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iomanip>
using namespace std;
const int maxn = 111;
double dp[maxn][maxn][maxn];
int A, B, C;
double dfs(int a, int b, int c, int dep)
{
if(dp[a][b][c] != 0) return dp[a][b][c];
if(a >= 100 || b >= 100 || c >= 100) return dp[a][b][c] = dep;
double res = 0, sum = a + b + c;
if(a) {
res += a / sum * dfs(a + 1, b, c, dep + 1);
}
if(b) {
res += b / sum * dfs(a, b + 1, c, dep + 1);
}
if(c) {
res += c / sum * dfs(a, b, c + 1, dep + 1);
}
return dp[a][b][c] = res;
}
int main()
{
cin >> A >> B >> C;
memset(dp, 0, sizeof(dp));
cout << setprecision(7) << dfs(A, B, C, 0) << endl;
return 0;
}
Solution:
bfs,注意已经扩展过的字母在任何其他位置都不需要再扩展,因此直接删除这个字符的扩展即可(否则超时)
#include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <string>
#include <queue>
#include <list>
using namespace std;
const int maxn = 2111;
const int mov[4][2] = {{0, 1}, {0, -1}, {1, 0}, {-1, 0}};
char mp[maxn][maxn];
int vis[maxn][maxn];
list<pair<int, int>> box[30];
int h, w;
int bfs(pair<int, int> be, pair<int, int> ed)
{
if(be == ed) return 0;
queue<pair<pair<int, int>, int>> que;
que.push(make_pair(be, 0));
memset(vis, 0, sizeof(vis)); vis[be.first][be.second] = 1;
while(!que.empty()) {
auto now = que.front(); que.pop();
if(now.first == ed) return now.second;
int x = now.first.first;
int y = now.first.second;
int sp = now.second;
for(int i = 0; i < 4; ++i) {
int nx = x + mov[i][0];
int ny = y + mov[i][1];
if(nx < 0 || ny < 0 || nx >= h || ny >= w) continue;
if(vis[nx][ny] || mp[nx][ny] == ‘#‘) continue;
vis[nx][ny] = 1;
que.push(make_pair(make_pair(nx, ny), sp + 1));
}
if(mp[x][y] >= ‘a‘ && mp[x][y] <= ‘z‘) {
vector<list<pair<int, int>>::iterator> mid;
for(list<pair<int, int>>::iterator it = box[int(mp[x][y] - ‘a‘)].begin(); it != box[int(mp[x][y] - ‘a‘)].end(); it++) {
que.push(make_pair(*it, sp + 1));
mid.push_back(it);
}
for(auto k : mid) box[int(mp[x][y] - ‘a‘)].erase(k);
}
}
return -1;
}
int main()
{
cin >> h >> w;
for(int i = 0; i < h; ++i) {
cin >> mp[i];
}
pair<int, int> S, G;
for(int i = 0; i < h; ++i) {
for(int j = 0; j < w; ++j) {
if(mp[i][j] == ‘S‘) {
S = make_pair(i, j);
}
else if(mp[i][j] == ‘G‘) {
G = make_pair(i, j);
}
else if(mp[i][j] >= ‘a‘ && mp[i][j] <= ‘z‘) {
box[int(mp[i][j] - ‘a‘)].emplace_back(i, j);
}
}
}
cout << bfs(S, G) << endl;
return 0;
}
Solution:
数据为40个,因此直接搜索会超时,但是如果数据降到20,我们就可以用dfs或者集合子集枚举的方式求出所有可能解,因此这题将数据分成前后两半考虑,分别求出所有可能之后,二分求出最后答案。
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <set>
using namespace std;
typedef long long ll;
const int maxn = 44;
ll a1[maxn], a2[maxn], n, t;
vector<ll> b1, b2;
int main()
{
freopen("in.in", "r", stdin);
cin >> n >> t;
int l1 = 0, l2 = 0;
for(int i = 0; i < n / 2; ++i) {
cin >> a1[i];
l1++;
}
for(int i = n / 2; i < n; ++i) {
cin >> a2[i - n / 2];
l2++;
}
for(int i = 0; i < (1 << l1); ++i) {
ll cost = 0;
for(int j = 0; j < l1; ++j) {
if(i & (1 << j)) cost += a1[j];
}
if(cost <= t)
b1.push_back(cost);
}
for(int i = 0; i < (1 << l2); ++i) {
ll cost = 0;
for(int j = 0; j < l2; ++j) {
if(i & (1 << j)) cost += a2[j];
}
if(cost <= t)
b2.push_back(cost);
}
sort(b1.begin(), b1.end());
sort(b2.begin(), b2.end());
l1 = int(unique(b1.begin(), b1.end()) - b1.begin());
l2 = int(unique(b2.begin(), b2.end()) - b2.begin());
ll ans = 0;
for(int i = 0; i < l1; ++i) {
ll k = b1[i];
int ad = int(upper_bound(b2.begin(), b2.begin() + l2, t - k) - b2.begin());
ad--;
if(ad >= 0 && b2[ad] + k <= t) ans = max(ans, b2[ad] + k);
}
cout << ans << endl;
return 0;
}
标签:遍历 contest bfs names 步骤 超时 mem clu memset
原文地址:https://www.cnblogs.com/LeafLove/p/14025745.html