《看了受制了》第一天,5道题,合计5道题
2023年8月26日 受制了系列第一天
ACWING 5081 重复局面
题目理解
就是匹配8*8的字符串出现的次数,我们把它们存在了vector里面,然后每次进行匹配即可。如果之前出现过就cnt++。
代码实现
#include<bits/stdc++.h>
using namespace std;
const int N = 110;
vector<string> m;
int main()
{
int n;
cin >> n;
m.push_back("");
for(int i = 0; i < n; i++)
{
int cnt = 1;
for(int j = 0; j < 8; j++)
{
string s;
cin >> s;
m.push_back(s);
}
for(int j = 0; j < i; j++)
{
int flag = true;
for(int k = 1; k <= 8; k++)
if(m[j * 8 + k] != m[i * 8 + k])
{
flag = false;
break;
}
if(flag)
cnt ++;
}
cout << cnt << endl;
}
return 0;
}
ACWING 5017垦田计划
题目理解
这个题目,需要使用二分来进行找最小的时间。我们只需要继续二分,切记!
对于二分如果找最小mid = (l + r) >> 1,然后是r = mid, l = mid + 1;
随后二分找最大mid = (l + r + 1) >> 1; l = mid, r = mid - 1;
代码实现
#include<iostream>
#include<vector>
#include<cmath>
using namespace std;
int n, k, m;
vector<int> t, c;
bool check(int mid)
{
int flag = true;
int tmp_m = m;
for(int i = 0; i < t.size(); i++)
{
if(t[i] > mid)
{
tmp_m -= (t[i] - mid) * c[i];
}
if(tmp_m < 0)
flag = false;
if(!flag)
break;
}
if(flag) return true;
return false;
}
int main()
{
cin >> n >> m >> k;
int l = k, r = -1;
for(int i = 1; i <= n; i++)
{
int a, b;
cin >> a >> b;
t.push_back(a);
c.push_back(b);
r = max(a, r);
r = max(b, r);
}
r++;
while(l < r)
{
int mid = (l + r) >> 1;
if(check(mid))
r = mid;
else
l = mid + 1;
}
cout << l;
return 0;
}
ACWING5165 CCC单词搜索
题目理解
对于字母的8个方向进行枚举。然后枚举的时候,要记得可以转一次弯弯。转弯只能转90度的。然后记录一下路径,进行匹配路径是否出现过,如果出现过就不能算了。这个题大佬的复杂度是我的1/10.....
代码实现
#include<iostream>
#include<vector>
using namespace std;
const int N = 110;
char p[N][N];
string s;
int n, m;
int cnt;
int d_x[9] = {0, -1, 1, 0, 0, -1, -1, 1, 1}; // 8个方向
int d_y[9] = {0, 0, 0, -1, 1, -1, 1, -1, 1};
vector<vector<pair<int, int>>> all;
void dfs(int l, int r, int u, int q, int turn, vector<pair<int, int>> c)
{
c.push_back({l, r});
if(l > n || r > m || l < 1 || r < 1) return ; //越界
if(u == s.size()) return; // 步数超过了
if(p[l][r] != s[u]) return;
if(u == s.size() - 1)
{
for(int i = 0; i < all.size(); i++)
if(c == all[i])
return;
all.push_back(c);
cnt++;
return;
}
// 不转弯
dfs(l + d_x[q], r + d_y[q], u + 1, q, turn, c);
if(turn == 0) //没转过弯才能转弯
{
// 枚举90度转弯
if(q == 1 || q == 2)
{
q = 3;
dfs(l + d_x[q], r + d_y[q], u + 1, q, 1, c);
q = 4;
dfs(l + d_x[q], r + d_y[q], u + 1, q, 1, c);
}else if(q == 3 || q == 4)
{
q = 1;
dfs(l + d_x[q], r + d_y[q], u + 1, q, 1, c);
q = 2;
dfs(l + d_x[q], r + d_y[q], u + 1, q, 1, c);
}else if(q == 5 || q == 8)
{
q = 7;
dfs(l + d_x[q], r + d_y[q], u + 1, q, 1, c);
q = 6;
dfs(l + d_x[q], r + d_y[q], u + 1, q, 1, c);
}else if(q == 7 || q == 6)
{
q = 5;
dfs(l + d_x[q], r + d_y[q], u + 1, q, 1, c);
q = 8;
dfs(l + d_x[q], r + d_y[q], u + 1, q, 1, c);
}
}
}
int main()
{
cin >> s;
cin >> n >> m;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
cin >> p[i][j];
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
for(int k = 1; k <= 8; k++)
{
vector<pair<int, int>> c;
dfs(i, j, 0, k, 0, c);
}
}
cout << cnt;
return 0;
}
ACWING 5166对称山脉
题目理解
这个题目,亮点在于当我们正向枚举的时候它是O(N^3)但是从中间开始,枚举每一个区间就是O(N^2)。非常的帅气。
大概是需要从中间开始,每次扩张每次扩张,然后更新每一个长度的最小值,记得分奇偶。
代码实现
#include<iostream>
#include<cstring>
#include<vector>
using namespace std;
const int N = 5010;
int res[N];
int a[N];
int n;
int main()
{
memset(res, 0x3f, sizeof res);
cin >> n;
for(int i = 0; i < n; i++)
{
cin >> a[i];
}
for(int i = 0; i < n; i ++)
{
int s = 0;
for(int l = i, r = i; l >= 0 && r < n; l--, r++) // 枚举奇数
{
s += abs(a[l] - a[r]);
res[r - l + 1] = min(res[r - l + 1], s);
}
s = 0;
for(int l = i, r = i + 1; l >= 0 && r < n; l--, r++) //枚举偶数
{
s += abs(a[l] - a[r]);
res[r - l + 1] = min(res[r - l + 1], s);
}
}
for(int i = 1; i <= n ;i++)
cout << res[i] << " ";
return 0;
}
ACWING 5164所有三角形
题目理解
- 如果左边或右边有连结的三角形,那么答案总数减去2
- 如果为奇数并且上面和下面有三角形,那么答案总数减去2
代码实现
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
int a[3][N];
int ans, n;
int main()
{
cin >> n;
for(int i = 1; i <= 2; i++)
for(int j = 1; j <= n; j++)
{
cin >> a[i][j];
if(a[i][j]) ans += 3;
}
for(int i = 1; i <= n; i++)
{
if(a[1][i] == 1 && a[1][i + 1] == 1) ans -= 2;
if(a[1][i] == 1 && a[2][i] == 1 && i % 2) ans -= 2;
if(a[2][i] == 1 && a[2][i + 1] == 1) ans -= 2;
}
cout<< ans;
return 0;
}

浙公网安备 33010602011771号