2022年秋招 网易雷火 算法题四道

第一道 100%

题面
题目描述

现在有一个加密的规则:给定长度不超过300个字符的一串文字(仅由大写字母或空格组成),将每个字符转为ASCII码后再加上一个魔法数 X(0<= X <= 999) 后组成了一串新的数字组合,加密的过程就完成了。现在想知道一串数字组合经过解密后的文字是什么,请编写代码帮助他。(如果只有—种解法,输出解密后的文字;如果没有解法或有多种解法,输出解法的个数)。
大写字母A-Z的ASCII码65-90;空格的ASCII码是32。

输入描述

第一行是数字N(1<=N<=300)
第二行是个数字(每个数字的大小范围大于40且小于200),以空格分开

输出描述

1个数字解密后的文字(解法唯一的时候)或解法数里(无解或有多个解的时候)

输入
15
82 79 86 86 89 42 97 89 92 86 78 42 100 100 100

输出
HELLO WORLD ZZZ

直接模拟就好了,习惯用vector a(n+1)和vector ans了

代码

#include <bits/stdc++.h>
#include <string>
#include <vector>
#include <map>
#define ll long long 
using namespace std;
const int N = 1e6+10;
 
int main()
{
	int n;	cin>>n;
	vector<int> a(n+1);
	for(int i=1; i<=n; i++)	cin>>a[i];
	vector<string> ans;
	for(int x=0; x<=999; x++)
	{
		int ok=1;
		for(int i=1; i<=n&&ok; i++)
		{
			int m = a[i]-x;
			if(m==32||m>=65&&m<=90) continue;
			ok = 0;
		}
		if(ok) 
		{
			string s;
			for (int i=1; i<=n; i++)
				s.push_back((char)(a[i]-x));
			ans.push_back(s);
		}
	}
	if(ans.size()!=1) printf("%d\n",ans.size());
		else cout << ans[0] << "\n";
	return 0;
} 




第二道题

题面

题目描述

假设游戏里目前有如下一些颜色标记(实际情况下,标记还包括文字加用、斜体、下划线、emoji、链接等,以及#转义相关的处理,这里进行简化以减少编码工作量)

#R:RGB预色标记,对应十六进制颜色码为0xFF0000
#G:RGB颜色标记,对应十六进制颜色码为0x00C932

#B:RGB颜色标记,对应十六进制颜色码为0×0000FF

#K:RGB颜色标记,对应十六进制颜色码为0x000000

#Y:RGB颜色标记,对应十六进制颜色码为0xFFFF00

#W:RGB颜色标记,对应十六进制颜色码为0xFFFFFF

#P:RGB颜色标记,对应十六进制颜色码为0xFF88FF

#CXXXXXX: RGB颜色标记,其中XXXXXX代表十六进制颜色码,每一位‘X’可以从数0-9及字母A-F这16个字符中取值,如果XXXXXX不是十六进制颜色码,则#C当做一般的字符串处理。

#n:颜色标记结束符,如果没有,则表示颜色影响一直持续到文本结束

文本中可同时存在多个颜色标记以及标记结束符,它们可能嵌套出现,并且标记与结束符不一定成对出现;
当文本中出现一个颜色标记时,之后的文字会以该标记对应的颜色显示;
当文本中出现一个额色标记结束符时,当前颜色标记失效,之后的文字会以上一个标记对应的颜色显示,如果不存在上一个标记,则之后的文字显示不会受到标记系统的影响。
通过组合使用这些颜色标记,就可以实现五颜六色富于变化的文字效果,比如下面这段文字;

#P盘古#n有斧,开天辟地,力竭而亡。#C00FF00#CFF0000清气#n升,为天;#C0000FF浊气#n降,土地#n,元气衍生出万物,催发生机。魔气衍生出死亡堕落,迷乱毁灭。宇宙万物,有正,则必有反。

然后,假设不带颜色标记时文字显示为白色,给出了上述文本最终对应的效果为:

现在给定一组带有上述颜色标记的文本,请你找出被标记了颜色的文本,以及文本对应十六进制RGB颜色值(六位大写字符串),如果该文本为空字符串的话,则无需输出。

输入描述

首先输入一个整教M(1<=M=10),表示有M组数据。
接下来依次输入各组数据,每组数据为一段带有颜色标记的文本Si。为了简化起见,Si由字母、数字、英文标点及符号组成,颜色标记均为大写,字符串长度不超过255。每组数据为一行。

输出描述

M组数据,每组教据分成N行显示。
第 i(1<=i<=N)行显示内容为第 i 段被颜色标记的文本,以及该文本对应的十六进制颜色值(大写字符串),以空格区分。颜色值相同,但是颜色标记不同的相邻文本需要分开输出。如果没有任何诚颜色标记的文本需要输出,则输出一行"empty"字符串即可。

输入
1

输入
2

GPT 提供解法

#include <iostream>
#include <string>
#include <stack>

using namespace std;

string getHexRGB(string color) {
    // 根据颜色标记获取十六进制RGB颜色码
    if (color == "#R") {
        return "FF0000";
    }
    else if (color == "#G") {
        return "00C932";
    }
    else if (color == "#B") {
        return "0000FF";
    }
    else if (color == "#K") {
        return "000000";
    }
    else if (color == "#Y") {
        return "FFFF00";
    }
    else if (color == "#W") {
        return "FFFFFF";
    }
    else if (color == "#P") {
        return "FF88FF";
    }
    else if (color[0] == '#' && color.length() == 7) {
        return color.substr(1); // 去除开头的#号
    }
    else if (color.length() == 8) {
        bool is_hex = true;
        for (int i = 0; i < 6; i++) {
            char c = color[i + 2];
            if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'F'))) {
                is_hex = false;
                break;
            }
        }
        if (is_hex == true) {
            return color.substr(2); // 去除开头的#C
        }
    }
    return "";
}

int main() 
{
    int m;
    cin >> m;
    getchar(); // 读取换行符 
    while (m--) 
    {
        string s, segment = "";
        stack<string> st;
        getline(cin, s);
        s += '\n'; // 在字符串末尾添加一个换行符,确保最后一段文本也能被处理
        for (int i = 0; i < s.length(); i++) {
            if (s[i] == '#') { // 颜色标记开始
                if (segment != "") {
                    st.push(segment + " empty"); // 将上一个段落存入栈中
                }
                segment = "#";
                while (1) 
                { // 获取颜色标记完整字符串
                    i++;
                    segment += s[i];
                    if (s[i] == 'n') {
                        break;
                    }
                }
                string hex_color = getHexRGB(segment);
                if (hex_color != "") 
                {
                    st.push(hex_color); // 将颜色码存入栈中
                }
                segment = "";
            }
            else {
                segment += s[i];
            }
        }
        int cnt = 0;
        while (st.empty() == false) {
            string str = st.top();
            st.pop();
            if (str.find("empty") == string::npos) { // 如果不是空字符串则输出
                cnt++;
                cout << str << " ";
                if (cnt % 2 == 0) {
                    cout << endl;
                }
            }
        }
        if (cnt % 2 != 0) { // 处理最后一行只有一个文本的情况
            cout << endl;
        }
    }

    return 0;
}



米莱虾提供解法

#include <bits/stdc++.h>
using namespace std;
typedef pair<string,string> PSS;
const int N = 1e3+10;
map<string,string> mp;
 
void init()
{
	mp["#R"] = "FF0000";
	mp["#G"] = "00C932";
	mp["#B"] = "0000FF";
	mp["#K"] = "000000";
	mp["#Y"] = "FFFF00";
	mp["#W"] = "FFFFFF";
	mp["#P"] = "FF88FF";
} 
 
int main()
{
	init();
 
	int t; cin>>t;
	getchar();
	while(t--)
	{
		string s; getline(cin,s);
		int n = s.length();
		vector<string> sta;
		vector<string> col(n);
		for(int i=0; i<n; i++) 
		{
			if(s[i]=='#') 
			{
				int j=i+1;
				if(j<n) 
				{
					string tmp="#";
					tmp.push_back(s[j]);
					int ok=0;
					if(mp.count(tmp)) sta.push_back(mp[tmp]), ok=1;
					else if(s[j]=='n' && !sta.empty()) sta.pop_back(), ok=1;
					if(ok) 
					{
						i=j;
						continue;
					}
				}
				j=i+7;
				if(j<n) 
				{
					int ok=1;
					if(s[i+1]!='C') ok=0;
					for(int k=i+2; k<=j; k++) 
					{
						char op = s[k];
						if(op>='0' && op<='9' || op>='A' && op<='F') continue;
						ok=0; 
						break;
					}
					if(ok) 
					{
						sta.push_back(s.substr(i+2,6));
						i=j;
						continue;
					} 
				}
			}
			if(!sta.empty()) {
				col[i] = sta.back();
				continue;
			}
		}
		
		vector<PSS> res;
		string path = "", _col = "";
		for(int i=0; i<n; i++) 
		{
			if(col[i]=="") 
			{
				if(path!="") res.push_back({path,_col}), path="", _col="";
				continue;
			}
			if(_col==col[i]) path.push_back(s[i]);
			else {
				if(path!="") res.push_back({path,_col});
				path="", path.push_back(s[i]), _col=col[i];
			}
		}
		if(path!="") res.push_back({path, _col});
		for(auto it: res) cout<<it.first<<" "<<it.second<<endl;
	}
	return 0;
} 



第三道 野炊

<50% 这题目还有GIF图示hh,顶不住,Code找不到了

题面
题目描述

一个W·H的地图上长满了草,每株草占一个格子,草被点然之后会向四周(以当前位置为中心的九宫格)蔓延,每隔一秒蔓延一次(每株草只会向四周蔓延一次),最多蔓延5次(即最多有11·11格子的草燃烧)。

草燃烧3秒后会消失,燃烧中或失的草无法用于蔓延也无法用于点然,过5秒后重新长出来。当点燃或蔓延竞争同一格子时,蔓延次数越少的优先级越高,点燃等于蔓延了0次。

地图内有N个食物,每个食物都在不同的位置,给出每个食物所在的位置 x,y,烧熟需要燃烧的时间t (食物所在位置的草的燃烧时间等于食物的然烧时间) 。

给出M个草的点燃位置a, b,在第c秒点燃,问最后有几种食物能被烧熟。

输入描述

第一行输入两个整数W和H(1<=W,H<=200)。表示地图的宽度和长度。第二行输入一个整数N(1<= N <=50),表示地图上的食物数量。
接下来的 N 行,每行是三个整数 x,y,t(0 <= X <= W, 0 <= y <= H, 1 <= t <= 30),表示食物的坐标 (x,y) 和烧熟所需的时间t。
然后一行输入一个整数M (1 <= M <= 50),表示点燃草的数量。
接下来和的M行,每行是三个整数 a,b,c (0 <= a <= W, 0 <= b <= H, 1 <= c <= 100),表示点燃的坐标 (a,b) 和点燃的时间点c。

输出描述

输出—个整数,表示烧熟的食物数量。

输入
20 20
1
6 15 3
3
0 19 1
10 9 1
4 13 5
输出

1


<br>

这是一个模拟题。题目的关键是对草蔓延和食物烧熟的判断。我们可以使用整数数组fire_map表示每个格子上的草燃烧时间以及定时刷新情况。

思路讲解:

1. 使用一个名为fire_map[W][H]的二维数组来记录地图每个格子草的燃烧时间。将数组中所有元素初始化为-1,表示草未被点燃。
 
2. 遍历M次,即点燃草的数量,并根据输入a,b,c,将fire_map更新:

   1) 将fire_map[a][b]设置为c,表示在位置(a,b)上的草在第c秒被点燃。

3. 接下来进行5次蔓延操作:

   1) 遍历整个fire_map,检查每个格子上的草是否被点燃。如果被点燃且燃烧时间不超过当前格子,那么让周围九宫格内的草蔓延燃烧。
   
   2) 更新fire_map矩阵,并将正在燃烧的草+1。如果已燃烧3秒的草,则消失,设置为-1。遍历完毕后,进行下一次蔓延。

4. 我们现在有的是含有所有蔓延后草的燃烧时间的地图(fire_map),接下来遍历所有食物的位置和所需烧熟时间:

   1) 检查当前食物位置(x, y)上的fire_map值是否等于所需烧熟时间t,如果相等,则food_count+1。

5. 输出food_count作为最终结果。

C++题解代码如下:

```cpp
#include <iostream>
#include <vector>

using namespace std;

int main() {
    int W, H;
    cin >> W >> H;
    int N;
    cin >> N;
    vector<vector<int>> foods(N, vector<int>(3, 0));
    for (int i = 0; i < N; i++) {
        cin >> foods[i][0] >> foods[i][1] >> foods[i][2];
    }
    int M;
    cin >> M;
    vector<vector<int>> burn_positions(M, vector<int>(3, 0));
    for (int i = 0; i < M; i++) {
        cin >> burn_positions[i][0] >> burn_positions[i][1] >> burn_positions[i][2];
    }

    vector<vector<int>> fire_map(W + 1, vector<int>(H + 1, -1));

    for (int i = 0; i < M; i++) {
        int a =




第四道

按理说应该AC的,没找到是哪个小错误导致了WA

题面

题目描述

有时候需要美术在地图上刷一片区域,用于特殊判定。地图是按照格子进行数据存储的。美术找到你,希望你能给他做一个工具,如果绘制的格子能形成一个封闭区域,就白动填充中间区域(如果存在多个封闭区域都会进行自动填充)。如下图是其中一个封闭区域填充展示:

封闭的定义:每个格子周围有上、下、左、右、左上、右上、左下、右下共八个相邻的格子,如果某个被刷格子A周围存在其他被刷格子B,我们称A和B是“相邻联通”的。如果被刷格子能通过“相邻联通"形成一个封闭区域,我们就说这些格子是封闭的,需要进行自动填充。
当美术一次绘制中存在多个封闭区域,所有封闭区域都需要进行自动填充。如果不存在封闭区域,不进行自动填充(注意此时,美术刷的格子还是属于被刷区域的)

输入描述

N M(N和M是整数,分别表示地图的长和宽,范围都是[100,100000]。)
P (美术—共刷了P个格子,P范围是[0,100000]。后续跟P个格子的位置数据每个数据用整数X,Y表示。X和Y是整数,X范围[0,N-1],Y范围[0,M-1]。每个数用一个空格隔开。)
X1,Y1 X2,Y2....Xp,Yp
(Q个需要查询是否属于被刷区域的格子位置数据,Q范围是[10,100000]。后续跟Q个格子的位置数据,每个数据用X,Y表示。X和Y是整数,X范围[0,N-1],Y范围[0,M-1]。每个数据用一个空格隔开)
X1,Y1 X2,Y2....Xq,Yq

输出描述

R1R2R3....Rq(Q个检测结果,1表示属于被刷区域,0表示不属于被刷区域)

输入
100 100
14
1,1 1,2 1,3 1,4 1,5 2,1 2,5 3,1 3,4 3,5 4,1 4,2 4,3 4,4

10
0,0 1,1 2,2 3,3 4,4 5,5 60,60 70,70 80,80 90,90

输出
0111100000

代码

#include <bits/stdc++.h>
using namespace std;
typedef pair<int,int> PII;
int dir[8][2] = {-1,0,1,0,0,-1,0,1,-1,-1,-1,1,1,-1,1,1};
 
int eval(string s)
{
	int val = 0;    
	for(auto x: s) val = val*10 + x - '0';	  
	return val;
}
 
PII get_val(string s) 
{
	int pos = -1;
	for(int j=0; j<s.length(); j++)
		if(s[j]==',')	pos=j;
	int x = eval(s.substr(0,pos));
	int y = eval(s.substr(pos+1));
	return {x,y};
}
 
int main()
{
	int n,m;    scanf("%d %d",&n,&m);
	vector<vector<int>> a(n+2, vector<int>(m+2,0));
	int p; scanf("%d",&p);
	for(int i=1; i<=p; i++)	
	{
		string s;    cin>>s;
		PII p = get_val(s);
		a[p.first][p.second] = 1;
	}
	
	queue<PII> qu;    
	qu.push({0,0}); 	
	a[0][0] = 2;
	while (!qu.empty())	
	{
		auto cur = qu.front();	qu.pop();
		int x=cur.first, y=cur.second;
		for (int d=0; d<8; d++)	
		{
			int nx = x + dir[d][0];
			int ny = y + dir[d][1];
			if(nx<0 || nx>n+1 || ny<0 || ny>m+1) continue;
			if(a[nx][ny]!=0) continue;
			a[nx][ny] = 2;
			qu.push({nx,ny});
		}
	}
	
	int q;   scanf("%d",&q);	
	string ans = "";
	while (q--)	
	{
		string s;	cin>>s;
		PII p = get_val(s);
		int x = p.first, y = p.second;
		if(a[x][y]==0 || a[x][y]==1) ans.push_back('1');
		else ans.push_back('0');
	}
	cout << ans << endl;
	return 0;
} 
posted @ 2023-04-20 15:56  专心Coding的程侠  阅读(69)  评论(0编辑  收藏  举报