《看了受制了》第十五天,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号