编程题C语言写牛牛数星星,编程题练习&题解|校招全国统一模拟笔试(六月场)...

原标题:编程题练习&题解|校招全国统一模拟笔试(六月场)

在线练习地址:

校招全国统一模拟笔试技术类编程题汇总:https://www.nowcoder.com/test/11086583/summary

(温馨提示:请使用地电脑进行练习~)

牛牛偶像养成记

分析

题目给出了n次牛牛能够上台的起始时间和持续时间,那么,我们可以通过这两个时间求到每次表演的结束时间。要使得牛牛上台的次数越多,那么就只有让牛牛上一个节目的结束时间越早,能留出更多的时间来选择后面更多的上台机会。所以,我们只需要将牛牛所有节目的结束时间从小到大排序,每次取满足条件的结束时间最早的节目就行了。

时间复杂度分析

O(nlogn)

参考代码

#include

using namespace std;

const int maxn = 1e5 + 5;

struct node {

int start, ed;

};

node a[maxn];

int n, m;

bool cmp(node x,node y) {

if(x.ed != y.ed)

return x.ed < y.ed;

else

return x.start < y.start;

}

int main() {

cin >> n;

for(int i = 0; i < n; i++) {

cin >> a[i].start >> m;

a[i].ed = a[i].start + m;

}

sort(a, a + n, cmp);

int ans = 0, t = 0;

for(int i = 0; i < n; i++) {

if(t <= a[i].start) {

ans++;

t = a[i].ed;

}

}

cout << ans << endl;

return 0;

}

牛牛与妞妞

分析

因为一共只有13种排,我们把剩下的那张牌从1到13把所有情况都跑一遍,复杂度也就13*13,是完全能够接受的。注意在枚举剩下那张牌多大的时候,要注意前面这张牌是否已经使用过4次了(因为每张牌最多只有4张),那么,我们枚举的次数就是我们的分母,枚举完后满足条件的答案便是分子,最后分子分母相除便能够得到我们的答案。

时间复杂度

O(13^2)

参考代码

#include

using namespace std;

int a1, b1, c1, a2, b2, c2;

int vis[15];

int main() {

memset(vis, 0, sizeof(vis));

scanf("%d%d%d", &a1, &b1, &c1);

vis[a1]++;

vis[b1]++;

vis[c1]++;

scanf("%d%d%d", &a2, &b2, &c2);

vis[a2]++;

vis[b2]++;

vis[c2]++;

int sum1 = a1 + b1 + c1;

int sum2 = a2 + b2 + c2;

sum1 = sum1 - sum2;

int l = 0, r = 0;

for(int i = 1; i <= 13; i++) {

if(vis[i] == 4)

continue;

else {

vis[i]++;

for(int j = 1; j <= 13; j++) {

if(vis[j] == 4)

continue;

else {

r++;

if(sum1 + i > j)

l++;

}

}

vis[i]--;

}

}

double ans = (double)l / (double)r;

printf("%.4fn", ans);

return 0;

牛牛数星星

分析

从数据规模可以看到,我们一共有10万颗星星以及最多10万次查询,如果我们每次查询都把给出的范围内遍历一遍的话肯定会超时。那么,我们就需要换一种方法。因为我们只需要得到一个矩形范围内的星星的数量,我们就可以先跑一遍整个数据范围,找到这个点的左上方向一共有多少颗星星,并把它标记出来。那么,我们要得到的矩形范围内的星星数量就变为了这个矩形右下角的点的值减去这个矩形左下角左边那个点的值再减去这个矩形右上角上面那个点的值再加上这个矩形左上角的左上边那个点的值(可以想象一下容斥定理)。那么,我们只需要遍历一次1000*1000的地图就行了,每个查询可以O(1)来获取。

时间复杂度

O(N^2)

参考代码

#include

using namespace std;

const int maxn = 1e3 + 5;

int n, m;

int num[maxn][maxn];

int mp[maxn][maxn];

int x, y;

int a1, b1, a2, b2;

int main() {

memset(num, 0, sizeof(num));

memset(mp, 0, sizeof(mp));

scanf("%d", &n);

for(int i = 0; i < n; i++) {

scanf("%d%d", &x, &y);

mp[x][y]++;

}

for(int i = 1; i < maxn; i++) {

for(int j = 1; j < maxn; j++) {

num[i][j] = num[i - 1][j] + num[i][j - 1] + mp[i][j] - num[i - 1][j - 1];

}

}

scanf("%d", &m);

for(int i = 0; i < m; i++) {

scanf("%d%d%d%d", &a1, &b1, &a2, &b2);

printf("%dn", num[a2][b2] - num[a1 - 1][b2] - num[a2][b1 - 1] + num[a1 - 1][b1 - 1]);

}

return 0;

}

牛牛与世界杯门票

分析

其实这个题我们可以把它转化为一个完全背包,背包的总重量为人数,背包内物品的价值为门票的价格。和普通完全背包不同的是,我们需要的背包总重量需要大于等于背包重量,而不是小于等于,也就是说,当背包剩余的重量不足以装下这个物品的时候才是我们得到答案的时候。因此,我们可以用一个if来判断装下这个物品后我们的重量是否小于等于0即可。

时间复杂度

O(n*m)

参考代码

const int maxn = 1e3 + 5;

int n,m,k,x,y;

int dp[maxn];

int main() {

scanf("%d%d%d", &n, &m, &k);

n++;

int ans = n * k;

for(int i = 1; i <= n; i++) dp[i] = i * k;

while(m--) {

scanf("%d%d", &x, &y);

if(y >= n)

ans = min(ans, x);

else {

for(int i = 1; i <= n; i++) {

if(i - y <= 0)

ans = min(ans, dp[i] + x);

else {

dp[i] = min(dp[i], dp[i - y] + x);

}

}

}

}

printf("%dn", ans);

return 0;

}

牛牛游玩记

分析

如果只有一个入口,那么这个题就是一个裸的BFS(DFS),但是改成多个入口之后呢?每一个都计算一次BFS(DFS)么?当然不。我们可以假象有一个超级起点,把这个起点连接上所有的入口,那么,这个题不就相当于一个入口一个出口了么。所以,我们只要把所有的起点在一开始都放入BFS的队列中,后面就按照普通的BFS写法就行了。

时间复杂度

O(n^2)

参考代码

#include

using namespace std;

const int maxn = 1e3 + 5;

const int dx[] = {0, 1, 0, -1};

const int dy[] = {-1, 0, 1, 0};

struct node {

int x, y;

};

int n, m;

int dis[maxn][maxn];

char mp[maxn][maxn];

node a, ed;

int main() {

memset(mp, 0, sizeof(mp));

memset(dis, -1, sizeof(dis));

queue q;

scanf("%d%d", &n, &m);

for(int i = 0; i < n; i++) {

scanf("%s", mp[i]);

}

for(int i = 0; i < n; i++) {

for(int j = 0; j < n; j++) {

if(mp[i][j] == '@') {

a.x = i;

a.y = j;

q.push(a);

dis[i][j] = 0;

}

if(mp[i][j] == '*') {

ed.x = i;

ed.y = j;

}

}

}

while(q.size()) {

node p = q.front();

q.pop();

for(int i = 0; i < 4; i++) {

int px = p.x + dx[i];

int py = p.y + dy[i];

if(dis[px][py] == -1 && px >= 0 && px < n && py >= 0 && py < n && mp[px][py] != '#') {

node pp;

pp.x = px;

pp.y = py;

q.push(pp);

dis[px][py] = dis[p.x][p.y] + 1;

if(px == ed.x && py == ed.y)

break;

}

}

if(dis[ed.x][ed.y] != -1) break;

}

printf("%dn", dis[ed.x][ed.y]);

return 0;

}

模拟笔试7月场报名: https://www.nowcoder.com/mockexam/MockExam返回搜狐,查看更多

责任编辑:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值