网易的笔试貌似是有好多题随机给四道做,看评论大家的题并不完全一样,我找到的四道题如下:
长度为n的数组a,找到一个最大的正整数d,使得对于所有i,a[i+1]-a[i]是d的倍数,即a[i+1]-a[i]=d×k(k≥1)
。
输入:
第一行一个正整数n,2<=n<=2*10^5
第二行n个正整数a[i],1<=a[i]<=10^18
输出:
若d不存在输出-1,否则输出最大的d。
样例1:
输入
4
1 3 7 15
输出
2
样例2
输入
3
5 5 5
输出
-1
d和k都必须是正整数,那么先把所有差值求出来排个序,如果最小值小于1那么必然不存在d,如果大于1则求所有差值的gcd即可。复杂度O(n)。
#include
#include
#include
#include
using namespace std;
int n;
long long a[200010];
long long cha[200010];
long long gcd(long long a, long long b)
{
return b ? gcd(b, a%b) : a;
}
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
{
cin >> a[i];
if (i)
cha[i-1] = a[i] - a[i-1];
}
sort(cha, cha + n-1);
if (cha[0] < 1) cout << -1 << endl;
else {
long long ans = cha[0];
for (int i = 1; i < n-1; i++)
ans = gcd(ans, cha[i]);
cout << ans << endl;
}
return 0;
}
最近牛牛约了几个同学一起去看电影,买了恰好数量的横排连坐票,但是有些同学关系很差,不愿意坐一起,牛牛想知道所有可能安排座位的情况。
输入:
第一行为两个数字n,k,代表总人数n和k个很差的关系。
接下来k行,每行两个数字x和y表示同学x与y之间关系很差,不能挨着坐,所有人编号为1到n。
1<=n<=9,0<=k<=100,保证x != y,可能有重复对。
输出:
每行输出一组解,按照字典序输出,相邻编号用空格隔开。
数据保证有解。
样例1:
输入
3 2
1 2
2 1
输出
1 3 2
2 3 1
样例2:
输入
3 0
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
数据量非常小,直接用深搜回溯即可,这样也能保证字典序,具体看代码。
#include
#include
#include
#include
using namespace std;
int n, k;
vector<vector<int> > v;//存放关系差的关系对
int vis[10];//标记已经排过位置的人
//index表示前一个位置坐的是谁, cnt用来计数当前已经排好了几个位置,now存放结果
void dfs(int index, int cnt, vector<int>& now)
{
if (cnt == n){
for (int i = 0; i < now.size(); i++){
if (i) cout << " ";
cout << now[i];
}
cout << endl;
return;
}
for (int i = 1; i <= n; i++) if (!vis[i]){
int flag = 1;
for (int j = 0; j < v[index].size(); j++) if (v[index][j] == i) {
flag = 0;
break;
}
if (flag){
vis[i] = 1;
now.push_back(i);
dfs(i, cnt+1, now);
now.pop_back();//回溯
vis[i] = 0;//回溯
}
}
}
int main()
{
cin >> n >> k;
v.resize(n+1);
int x, y;
for (int i = 0; i < k; i++){
cin >> x >> y;
v[x].push_back(y);
v[y].push_back(x);
}
for (int i = 1; i <= n; i++){//以i为头
memset(vis, 0, sizeof vis);//标记排过位置的人
vis[i] = 1;
vector<int> now(1, i);
dfs(i, 1, now);
}
return 0;
}
牛牛喜欢玩魔塔,魔塔里有n只怪,每只怪有两个属性,破防能力和伤害,当勇士挑战一只怪时,
1.勇士的防御力大于其破防能力,勇士不受伤害;
2.若小于等于,则受到等于怪伤害值的伤害;
初始防御力为D,勇者可以自行决定打哪个怪(任意顺序),每次打完一只怪防御力加1,那么勇者打完所有n只怪最少要承受多少伤害?
输入:
第一行为n和D,1<=n<=5000,1<=D<=5000
第二行有n个正整数Ai,表示第i号怪物的破防能力
第三行有n个正整数Bi,表示第i号怪物的伤害。
输出:
一个整数表示最少承受伤害。
样例1
输入
3 50
100 50 51
1000 1000 1000
输出
1000
解释:只要先抗住第一只怪,受1000伤害,防御力变为51,然后打第二只不受伤害,防御力变为52,再打第三只。
不太好做的题,首先感觉贪心可以搞,先去面对破防能力低的怪,但是如果破防能力低的怪也打不过,且伤害比破防能力高的怪还高,就很难受,比如样例,如果先打第二只怪其实受伤害更多。所以我选择把数据做两份,一份按照破防能力排序,一份按照伤害值排序,当防御力小于等于当前怪物(破防能力最低的)的破防能力时,说明当前防御力打谁都打不过,那就找伤害值最低的怪来打。
这里又出现了一个问题,直接举例来看
2 50
50 60
1 100
现在两只怪都打不过,那么选择伤害更低的来打,选了(50 1)的这只,这样最后要受101点伤害,如果直接选择(60,100),打完以后防御力变为51,最后只受100伤害。
所以要先把一定打不过的先打了,什么怪一定打不过?破防能力大于等于D+n-1的!!!所以先把这些怪打了,假如有m只,那么现在防御力变成了D+m。
然后把剩下的怪按照上面贪心的思路,存两份,然后不断打怪即可。
我的代码写的时候图方便,把破防能力小于D的也先去掉了。
这题n并不大,复杂度O(n^2)可以接受。
#include
#include
#include
#include
using namespace std;
struct node
{
int index;//存放怪物编号
int a, b;//破防, 伤害
node(int i = 0, int aa = 0, int bb = 0) : index(i), a(aa), b(bb){}
};
node defend[5010], attack[5010];
bool cmp1(const node & x, const node & y)//按破防从小到大
{
if (x.a == y.a) return x.b < y.b;
return x.a < y.a;
}
bool cmp2(const node & x, const node & y)//按伤害从小到大
{
if (x.b == y.b) return x.a > y.a;
return x.b < y.b;
}
int main()
{
int N, D;
cin >> N >> D;
int aa[N], bb[N];
for (int i = 0; i < N; i++) cin >> aa[i];
for (int i = 0; i < N; i++) cin >> bb[i];
int n = 0, sum = 0;
int d = D;
for (int i = 0; i < N; i++)
if (aa[i] >= D+N-1){
d++;
sum += bb[i];
}
else if (aa[i] >= D){
defend[n] = node(n, aa[i], bb[i]);
attack[n] = node(n, aa[i], bb[i]);
n++;
}
else d++;
sort(defend, defend+n, cmp1);
sort(attack, attack+n, cmp2);
int vis[n];//标记已经打过的怪编号
memset(vis, 0, sizeof vis);
int cnt = n;//还剩几只怪
int i = 0, j = 0;
while (cnt){
for (; i < n; i++) if (!vis[defend[i].index]){
if (defend[i].a < d){
vis[defend[i].index] = 1;
cnt--;
d++;
}
else break;//如果这只打不过,说明现在所有怪都打不过
}
//挑那只伤害值最低的
for (; j < n; j ++) if (!vis[attack[j].index]){
vis[attack[j].index] = 1;
cnt--;
d++;
sum += attack[j].b;
break;
}
}
cout << sum << endl;
return 0;
}
有一个n*m的网格,这个网格内有一些障碍物,同时也有一些激光,激光发出的光是一条直线,从该激光发射器到障碍物或其他激光发射器停止,现在小强想从一个点走到另一个点,每一步小强走到周围8个联通的点,但是要求走的路径中相邻两个格子最多只能有一个是有激光的,想知道这个路径中最少有几个格子是被激光照射的,若无法走到输出-1。
输入
第一行一个T,表示T组测试数据;
对于每一组测试数据,第一行两个数n和m表示网格大小。
第二行4个整数,x1,y1,x2,y2表示起点和终点。
第三行一个整数k,表示k个障碍物和激光
接下来k行,每一行二个整数一个字符x,y,op,表示(x,y)处的信息
op为u代表格子为激光且向上(UP)照射
op为d代表格子为激光且向下(DOWN)照射
op为l代表格子为激光且向左(LEFT)照射
op为r代表格子为激光且向右(RIGHT)照射
op为B表示障碍物,无法通过。(题目没说激光发射器位置是否可以通过,样例只能看出该位置也是有激光的)
1<=T<=100
1<=n,m<=20
输出
每组测试数据输出对应的结果。
样例:
输入
2
3 3
1 1 3 3
2
2 1 r
2 3 B
3 2
1 2 3 1
2
2 1 B
2 2 B
输出
1
-1
这题我写了半天,地图楞没建好,我觉得建好图dfs应该就能做了,但是建图实在太难受写不下去了。以后心情好的时候再写。笔试的时候遇到,怕也不一定有时间来写。
某游戏中有一个老用户带新用户的玩法,老用户跟新用户需要两两组队为n个队伍,现在,我们根据用户画像(这么真实的?),已经计算出每个新用户对所有老用户的组队偏好排序,以及每个老用户对所有新用户的组队偏好排序,请你实现一个匹配算法,要求:
1.根据新用户对老用户的偏好排序去匹配老用户;
2.如果被匹配过的老用户已有队友,根据老用户对新用户的偏好排序,为该老用户选择排在前面的新用户。
输入:
第一行一个n,表示新老用户总数,新老用户编号均为1到n;
接下来n行,第一个数字为新用户编号,接下来n个数字为该新用户对所有老用户的偏好排序;
再接下来n行,第一个数字为老用户编号,接下来n个数字为该老用户对所有新用户的偏好排序;
输出:
n行,每一行为队伍的新用户和老用户编号,空格隔开,按照新用户的编号从低至高排列。
样例:
输入
3
1 2 3 1
2 1 3 2
3 1 2 3
1 1 2 3
2 1 2 3
3 1 2 3
输出
1 2
2 1
3 3
这题实际上是一个匹配问题,我们模拟一下这个情况,如果现在有两个新用户选择了同一个老用户,那么就要按照这两个新用户在该老用户那里的优先级进行比较,然后配对,没有配成的那个人就选择他优先级里下一个老用户继续进行配对,不断进行这个过程,直到所有人都配对成功,所以仔细一想这就是个婚姻匹配问题,我借鉴了一下这篇博客的代码(好吧我是抄了一遍改了改),具体看代码:
#include
#include
#include
#include
using namespace std;
const int N = 1010;
int man[N][N], woman[N][N], match[N];//man[i][j]表示新人i心中排在第j位的老用户编号,woman[i][j]存放老人i心中第j位的新用户编号
//match存放匹配答案
int wm[N][N], choose[N], manIndex[N];
//wm[i][j]表示新人j在老人i心中的位置(优先级)
//choose[i]表示老人i现在选择的新人编号
//manIndex[i]表示新人i现在需要跟他心中第manIndex[i]个人进行匹配,前面man[i][1]到man[i][manIndex[i]-1]都被别人抢了
int n;
int main()
{
cin >> n;
int xin, lao;
for (int i = 1; i <= n; i++){
cin >> xin;
for (int j = 1; j <= n; j++){
cin >> lao;
man[xin][j] = lao;
}
}
for (int i = 1; i <= n; i++){
cin >> lao;
for (int j = 1; j <= n; j++){
cin >> xin;
woman[lao][j] = xin;
}
}
//初始化
for (int i = 1; i <= n; i++){
match[i] = -1;
choose[i] = -1;
manIndex[i] = 1;//从第一个人开始
for (int j = 1; j <= n; j++)
wm[i][woman[i][j]] = j;
}
bool bSingle = false;
while (!bSingle){
bSingle = true;
for (int i = 1; i <= n; i++){
if (match[i] != -1)//如果所有i都有匹配了,结束
continue;
bSingle = false;
int j = manIndex[i]++;
int w = man[i][j];//尝试匹配i和w
int m = choose[w];
//看一下w现在有没有配对的人,如果没有或者那个匹配的人的优先级不如i
if (m == -1 || wm[w][i] < wm[w][m]){
match[i] = w;
choose[w] = i;
if (m != -1)
match[m] = -1;//原来配上的取消掉
}
}
}
for (int i = 1; i <= n; i++)
cout << i << " " << match[i] << endl;
return 0;
}
《荒野行动》是网易游戏出品的一款战术竞技游戏,开局物资的获取对于玩家后续游戏发展影响很大,因此玩家都会在降落之后进行一波疯狂的物资搜集,而这些物资散落在地图的各个角落,受限于地图上建筑的阻挡,有些物资点是玩家无法到达的,假设我们用n*n的矩阵来表示地图,其中字符"."表示道路,字符“#”表示建筑,阿拉伯数字1~9表示物资,数值是物资的重量。玩家降落后有一个初始位置(x,y)其中0<=x,y
第一行一个整数n,6<=n<=3000,表示地图大小;
接下来n行,每行n个字符,表示地图;
接下来两个整数x,y,表示初始位置。
输出
搜集完毕后背包的重量
样例:
输入
6
…1.#.
2##3#8
.#.##.
.#6#9.
4###…
…7…5
0 0
输出
39
题目蛮长的,就是一个搜索题,不要求找路径的话用BFS写会好很多。具体看代码。
#include
#include
#include
#include
using namespace std;
int n, x, y;
int vis[3010][3010];
int dx[4] = {1, -1, 0, 0};
int dy[4] = {0, 0, 1, -1};
char mp[3010][3010];
int main()
{
cin >> n;
for (int i = 0; i < n; i++)
cin >> mp[i];
cin >> x >> y;
queue<pair<int, int>> que;
que.push(make_pair(x, y));
vis[x][y] = 1;
int ans = 0;
if (mp[x][y]>='1' && mp[x][y]<='9') ans += mp[x][y]-'0';
while (!que.empty()){
pair<int, int> now = que.front();
que.pop();
for (int i = 0; i < 4; i++){
int nx = dx[i] + now.first;
int ny = dy[i] + now.second;
if (nx<0 || nx>=n || ny<0 || ny>=n) continue;
if (mp[nx][ny]=='#' || vis[nx][ny]) continue;
que.push(make_pair(nx, ny));
vis[nx][ny] = 1;
if (mp[nx][ny]>='1' && mp[nx][ny]<='9')
ans += mp[nx][ny]-'0';
}
}
cout << ans << endl;
return 0;
}
中国电子游戏发展至今,经历了单机游戏、MMO端游、网页游戏、移动游戏等多种游戏类型,已经积累了大量的游戏忠实用户。随着大数据的迅速发展和普及,通过数据分析、挖掘来对游戏用户做研究,提升用户体验,变得越来越重要,下面是一份用户关注数据,表名src_tieba_user,表结构如下:
字段名 | 类型 | 说明 |
---|---|---|
tbaname | varchar | 贴吧名 |
username | varchar | 用户名 |
请仔细阅读并理解SQL,输出该SQL的执行结果。
SELECT
a.tbaname,
b.tbaname,
COUNT(DISTINCT a.username) AS num
FROM
src_tieba_user a
INNER JOIN
src_tieba_user b
WHERE
a.username = b.username AND a.tbaname != b.tbaname
GROUP BY
a.tbaname, b.tbaname
ORDER BY
a.tbaname, b.tbaname
HAVING
num>2;
输入
第一行一个整数n,1<=n<=3000,表示表中数据的记录数
接下来n行,每行两个字符串tbaname,username,字符串长度不超过10个字符,两个字符串空格分隔,表示数据表中的一条记录。
输出
结合输入数据,输出以上SQL的执行结果,每行数据的字段用空格分隔。
样例
输入
8
ddd Kate
ccc Kate
ccc Beal
eee Tom
ddd Beal
bbb Kate
ddd Tom
ccc Tom
输出
ccc ddd 3
ddd ccc 3
我还没学过SQL,之后再写吧。