《看了受制了》第十五天,6道题,合计64道题
2023年9月13日
今天开始刷PAT!每天尽可能多刷,预计11月左右刷完。
ACWING5218 密室逃脱
题目理解
这个题直接dfs的话,会TLE,且一定不要忘记越界。
优解的话是存下来权重,而且BFS遍历的是权重所对应的点,什么意思呢?就是预先处理所有i * j可以达成的点,比如(x, y)的权重是W,那么只需要遍历W权重下的点就可以了,而不是遍历所有点。
代码实现
#include<iostream>
#include<queue>
#include<cstdio>
using namespace std;
const int N = 1e6 + 10, M = 1010;
struct node{
int x, y;
};
int w[M][M];
bool st[M][M];
vector<node> p[N];
int m, n, flag;
void bfs(int x,int y)
{
queue<node> q;
q.push({x, y});
st[x][y] = true;
while(q.size())
{
node k = q.front();
q.pop();
int u = w[k.x][k.y];
for(int i = 0; i < p[u].size(); i++) // 只遍历权重的点
{
node e = p[u][i];
if(st[e.x][e.y]) continue;
if(e.x == m && e.y == n)
{
flag = 3;
return ;
}
st[e.x][e.y] = true;
q.push(e);
}
}
}
int main()
{
cin >> m >> n;
for(int i = 1; i <= m; i++)
for(int j = 1; j <= n; j++)
{
scanf("%d", &w[i][j]);
if(n * m == w[i][j])
flag = 1;
}
// 直接不找了,没答案的
if(flag != 1)
printf("no");
else
{
for(int i = 1; i <= m ; i++)
for(int j = 1; j <= n; j++)
p[i * j].push_back({i, j}); // 预先处理可以的权重
bfs(1, 1);
if(flag == 3)
printf("yes");
else
printf("no");
}
return 0;
}
ACWING1473 A+B格式
题目理解
把数字存下来,然后以字符串形式,倒着存一次没存三个存一个逗号。
代码实现
#include<iostream>
#include<vector>
using namespace std;
vector<int> v;
vector<char> p;
int main()
{
int a, b;
cin >> a >> b;
int c = a + b;
if(c < 0)
{
cout << "-";
c = -c;
}
while(c)
{
v.push_back(c % 10);
c /= 10;
}
if(!v.size())
v.push_back(0);
int k = 0;
for(int i = 0; i < v.size(); i++)
{
if(k % 3 == 0 && k > 0)
p.push_back(',');
p.push_back((char)(v[i] + 48));
k++;
}
for(int i = p.size() - 1; i >= 0; i--)
cout << p[i];
return 0;
}
ACWING1477 拼写正确
题目理解
就是先求和,然后一个个%10,切记还有zero。
代码实现
#include<iostream>
#include<vector>
using namespace std;
vector<string> p;
string s;
string a[] = {"zero", "one", "two", "three", "four", "five", "six", "seven", "eight", "nine", "zero"};
int res = 0;
int main()
{
cin >> s;
for(int i = 0; i < s.size(); i++)
res += ((int)(s[i]) - 48);
if(!res)
p.push_back("zero");
while(res)
{
p.push_back(a[res % 10]);
res /= 10;
}
for(int i = p.size() - 1; i >= 0; i--)
cout << p[i] << " ";
return 0;
}
牛客比赛 优美的序列
题目理解
因为所有的n的和小于1000可以写两重循环的。然后事先进行排序,就可以尽可能实现|a[i] - a[j]| ≥ |i - j|。
代码实现
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const int N = 1010;
int a[N], n;
int main()
{
int T;
cin >> T;
while(T--)
{
cin >> n;
memset(a, 0, sizeof a);
for(int i = 1; i <= n; i++)
cin >> a[i];
sort(a + 1, a + 1 + n);
int flag = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= n; j++)
if(abs(a[i] - a[j]) < abs(i - j))
{
flag = 1;
}
if(flag)
cout << -1;
else
for(int i = 1; i <= n; i++)
cout << a[i] << " ";
cout << endl;
}
return 0;
}
牛客比赛 优美的Gcd
题目理解
不难看出,直接k和k的n倍最大公约数必是k。
代码实现
#include<iostream>
using namespace std;
int main()
{
int n;
cin >> n;
while(n --)
{
int k;
cin >> k;
cout << k <<" " << k * 2 << endl;
}
return 0;
}
牛客比赛 最小的数字
题目理解
语法题
代码实现
#include<iostream>
using namespace std;
int main()
{
int n;
cin >> n;
while(n % 3 != 0)
{
n++;
}
cout << n;
return 0;
}

浙公网安备 33010602011771号