【官方题解】:https://www.nowcoder.com/discuss/65411?toCommentId=1134823

【题目链接】:https://www.nowcoder.com/test/question/8fd2b461f3874031a29bdf5aac3c8d51?pid=8527168&tid=12942913

1.

妞妞听说Nowcoder Girl女生编程挑战赛要开始了, 但是她没有足够的勇气报名参加, 牛牛为了帮助妞妞,给她准备一台勇气获得机。初始的时候妞妞的勇气值是0, 勇气获得机有两个按钮:

1、N按钮: 如果当期拥有的勇气值为x, 按下之后勇气值将变为2*x+1,

2、G按钮: 如果当前拥有的勇气值为x, 按下之后勇气值将变为2*x+2,

勇气值过高也会膨胀,所以妞妞需要将自己的勇气值恰好变为n, 请你帮助她设计一个勇气获得机的按键方案使妞妞的勇气值恰好变为n。

输入描述:

输入包括一行, 包括一个正整数n(1 <= n <= 10^9), 表示妞妞最后需要的勇气值。

输出描述:

输出一行字符串, 每个字符表示该次妞妞选择按动的按钮,'N'表示该次按动N按钮,'G'表示该次按动G按钮。

输入例子1:

20

输出例子1:

NGNG

【分析】:仔细观察会发现,每一步的按键方案由奇偶性确定,于是分类确定即可; 也可以用用while实现一个递归。
【代码】:
#include <bits/stdc++.h>

using namespace std;

int n;
stack<char> s;
int main() {
cin >> n;
while(n) {
if(n % == ) {
n = (n - ) / ;
s.push('G');
} else {
n = (n - ) / ;
s.push('N');
}
}
while(!s.empty()) {
printf("%c", s.top());
s.pop();
}
printf("\n");
return ;
}

O(logn)/分类讨论

作者:shiqitao
链接:https://www.nowcoder.com/discuss/65424?type=0&order=0&pos=6&page=0
来源:牛客网 #include <iostream>
#include <string>
using namespace std;
int main()
{
int n; cin >> n;
string result = "";
while (n != ) {
result = (n % ? "N" : "G") + result;
n = (n - ) / ;
}
cout << result;
return ;
}

递归


妞妞得到一个(1~n)的排列p1, p2, p3,...,pn, 听村里的老人牛牛说如果让这个排列变为:

对于所有的1 <= i <= n, 都满足pi ≠ i, 就可以获得Google Girl Hackathon的入场券。
妞妞仅允许的操作是: 交换排列中两个相邻的元素, 并且妞妞允许做这个操作任意次。

但是Google Girl Hackathon就快要开始了, 妞妞希望做最少的操作就使排列满足要求, 妞妞希望你能帮助她。

输入描述:
输入包括两行, 第一行包括一个正整数n(2 <= n <= 10^5), 表示排列的长度和范围。
第二行包括n个正整数p

1

, p

2

, p

3

,...,p

n

, 即妞妞得到的排列, 保证是一个1~n的排列。

输出描述:

输出一个整数, 表示妞妞需要的操作次数。

输入例子1:
5
1 4 3 5 2 输出例子1:
2
【分析】:如果某个数没有满足错排要求,直接和相邻的位置swap一下,统计次数即可。如果有一个pi=i或一对pi=i并且pi+1=i+1,则需要一次交换。
【代码】:
作者:NotDeep
链接:https://www.nowcoder.com/discuss/65411
来源:牛客网 #include <bits/stdc++.h> using namespace std; const int maxn = 1e5 + ; int a[maxn], n;
int main() {
cin >> n;
for(int i = ; i < n; i++) scanf("%d", &a[i]);
int res = ;
for(int i = ; i < n - ; i++) {
if(a[i] == i + ) {
swap(a[i], a[i + ]);
res++;
}
}
if(a[n - ] == n) res++;
cout << res << endl;
return ;
}

数论、错排

作者:shiqitao
链接:https://www.nowcoder.com/discuss/65424?type=0&order=0&pos=6&page=0
来源:牛客网 #include <iostream>
using namespace std;
int main()
{
int n; cin >> n;
int equal = , count = , data;
while (count < n) {
cin >> data;
if (data == ++count) {
if (count != n) cin >> data;
count++; equal++;
}
}
cout << equal;
return ;
}

Code2


妞妞参加完Google Girl Hackathon之后,打车回到了牛家庄。

妞妞需要支付给出租车司机车费s元。妞妞身上一共有n个硬币,第i个硬币价值为p[i]元。

妞妞想选择尽量多的硬币,使其总价值足以支付s元车费(即大于等于s)。

但是如果从妞妞支付的这些硬币中移除一个或者多个硬币,剩下的硬币总价值还是足以支付车费的话,出租车司机是不会接受的。例如: 妞妞使用价值为2,5,7的硬币去支付s=11的车费,出租车司机是不会接受的,因为价值为2这个硬币是可以移除的。

妞妞希望能选取最大数量的硬币,使其总价值足以支付车费并且出租车司机能接受。

妞妞希望你能帮她计算最多可以支付多少个硬币。

输入描述:

输入包括两行, 第一行包括两个正整数n和s(1 <= n <= 10, 1 <= s <= 1000), 表示妞妞的硬币个数和需要支付的车费。
第二行包括n个正整数p[i] (1 <= p[i] <= 100),表示第i个硬币的价值。
保证妞妞的n个硬币价值总和是大于等于s。

输出描述:

输出一个整数, 表示妞妞最多可以支付的硬币个数。

输入例子1:

5 9
4 1 3 5 4

输出例子1:

3
【分析】:最多只有10个硬币,简单遍历一下就可以啦。注意到n很小,直接枚举子集判断是否合法,在所有合法的方案中找size最大。
【代码】:
作者:shiqitao
链接:https://www.nowcoder.com/discuss/65424?type=0&order=0&pos=6&page=0
来源:牛客网 #include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n, s; cin >> n >> s;
int data[] = { };
for (int i = ; i < n; i++) {
cin >> data[i];
}
int result = ;
for (int i = ; i < pow(, n); i++) {
int mincoin = , sum = , sumcoin = ;
int temp = i;
for (int j = ; j < n; j++) {
if (temp % ) {
sum += data[j];
mincoin = mincoin < data[j] ? mincoin : data[j];
sumcoin++;
}
temp >>= ;
}
result = sum >= s && sum - mincoin < s ? result>sumcoin ? result : sumcoin : result;
}
cout << result;
return ;
}

简单遍历一下

作者:NotDeep
链接:https://www.nowcoder.com/discuss/65411
来源:牛客网 #include <bits/stdc++.h> using namespace std; int n, s, p[];
int main() {
scanf("%d%d", &n, &s);
for(int i = ; i < n; i++) scanf("%d", &p[i]);
int ans = ;
for (int x = ; x < ( << n); x++) {
int mi = ;
int sum = ;
int cnt = ;
for (int i = ; i < n; i++) {
if ((x & ( << i)) != ) {
mi = min(mi, p[i]);
sum += p[i];
cnt++;
}
}
if (sum >= s && sum - mi < s) {
ans = max(ans, cnt);
}
}
cout << ans << endl; }

O(2^n)


美丽的牛家庄受到了外星人的侵略, 勇敢的妞妞要上战场抵御侵略。

在妞妞上战场前, 村长牛牛给了妞妞N件装备, 妞妞需要选择其中的K件,装备在身上提升自己的战斗力。每件装备有5种属性增幅值,对于第i件装备它的属性增幅值为(ri1, ri2, ri3, ri4, ri5), 分别代表该装备对不同的属性值增幅。

当妞妞装备多件装备的时候,由于装备之前会互相影响, 对于每种属性值的增幅并不是所有装备该属性值之和, 而是该种属性值下所有装备中最大的属性值。而妞妞最终增加的战斗力为这5种属性值增幅之和。

妞妞一定要保卫牛家庄, 所以她希望她能提升尽可能多的战斗力, 请你帮帮她计算她最多能增加多少战斗力。

输入描述:

输入包括N+1行,

第一行包括两个正整数N和K(1 <= N <= 10000, 1 <= K <= N), 分别表示一共有的装备数量和妞妞需要选择的装备数量。

接下来的N行,每行5个整数ri1, ri2, ri3, ri4, ri5 (0 <= ri1, ri2, ri3, ri4, ri5 <= 10000)表示第i件装备的5种属性值增幅。

输出描述:

输出一个整数,表示妞妞最多能增加的战斗力。

输入例子1:

4 2
30 30 30 30 0
50 0 0 0 0
0 50 0 50 10
0 0 50 0 20

输出例子1:

170

例子说明1:

妞妞要从4件装备中选取2件, 如果妞妞选择第1件和第3件装备,那么增加的战斗力为30 + 50 + 30 + 50 + 10 = 170, 这是最大的方案。

【分析】:没有想到好办法,m大于等于5时取各个属性的最大值,m小于等于3时遍历,m等于4时为防止超时,用一点小小的技巧即可通过。
当k >= 5的时,每一维属性都取最大求和即可。
对于k < 5的时,预处理31种情况可能得到的最大的和。然后dfs枚举子集维护最大的答案即可。
【代码】:
作者:shiqitao
链接:https://www.nowcoder.com/discuss/65424?type=0&order=0&pos=6&page=0
来源:牛客网 #include <iostream>
#include <algorithm>
using namespace std;
int main()
{
int n, m; cin >> n >> m;
int **r = new int*[n], result = ;
int maxr[] = { };
for (int i = ; i < n; i++) {
r[i] = new int[];
for (int j = ; j < ; j++) {
cin >> r[i][j];
maxr[j] = max(maxr[j], r[i][j]);
}
}
if (m == ) {
for (int i = ; i < n; i++) {
int temp = ;
for (int k = ; k < ; k++) {
temp += r[i][k];
}
result = max(result, temp);
}
}
else if (m == ) {
for (int i = ; i < n; i++) {
for (int j = ; j < n; j++) {
int temp = ;
for (int k = ; k < ; k++) {
temp += max(r[i][k], r[j][k]);
}
result = max(result, temp);
}
}
}
else if (m == ) {
for (int i = ; i < n; i++) {
for (int j = ; j < n; j++) {
for (int p = ; p < n; p++) {
int temp = ;
for (int k = ; k < ; k++) {
temp += max(max(r[i][k], r[j][k]), r[p][k]);
}
result = max(result, temp);
}
}
}
}
else if (m == ) {
int maxtemp[][] = { };
for (int p = ; p < ; p++) {
for (int q = p + ; q < ; q++) {
int temp = ;
for (int i = ; i < n; i++) {
temp = max(temp, r[i][p] + r[i][q]);
}
for (int k = ; k < ; k++) {
if (k != p && k != q) {
temp += maxr[k];
}
}
result = max(result, temp);
}
}
}
else {
for (int k = ; k < ; k++) {
result += maxr[k];
}
}
cout << result;
return ;
}

冗长

作者:NotDeep
链接:https://www.nowcoder.com/discuss/65411
来源:牛客网 #include <bits/stdc++.h> using namespace std; const int maxn = 1e4 + ; int mx[];
int num[maxn][];
int N, K;
int sta[];
int dfs(int s, int cur) {
if(cur == K) return ;
int tmp = ;
for(int i = s; i; i = (i - ) & s) tmp = max(tmp, sta[i] + dfs(s ^ i, cur + ));
return tmp;
}
int main() {
scanf("%d%d", &N, &K);
memset(sta, , sizeof(sta));
memset(mx, , sizeof(mx));
for(int i = ; i < N; i++) {
for(int j = ; j < ; j++) {
scanf("%d", &num[i][j]);
mx[j] = max(mx[j], num[i][j]);
}
for(int j = ; j < ; j++) {
int res = ;
for(int k = ; k < ; k++) {
if(j & ( << k)) {
res += num[i][k];
}
}
sta[j] = max(sta[j], res);
}
}
if(K >= ) {
int ans = ;
for(int i = ; i < ; i++) ans += mx[i];
printf("%d\n", ans);
} else {
printf("%d\n", dfs(, ));
}
return ;
}

DFS


如果一个整数x是某个整数的平方, 我们就把整数x称为平方数。

妞妞最喜欢的数字就是平方数, 妞妞现在给你一个N, 妞妞希望你能帮助她找出不大于N的最大的平方数。

输入描述:

输入包括一行, 包括一个正整数N(1 <= N <= 10^9), 表示妞妞给的数字N。

输出描述:

输出一个整数, 即不大于N的最大的平方数。

输入例子1:

10

输出例子1:

9

【分析】:

#include <iostream>
#include <cmath>
using namespace std;
int main()
{
int n; cin >> n;
cout << (int)sqrt(n)*(int)sqrt(n) << endl;
return ;
} //////////////////////////////
#include <bits/stdc++.h>
using namespace std; int n;
int main() {
cin >> n;
int ans = ;
for(int i = ; i <= sqrt(n); i++) ans = i * i;
printf("%d\n",ans);
return ;
}

妞妞参加了Nowcoder Girl女生编程挑战赛, 但是很遗憾, 她没能得到她最喜欢的黑天鹅水晶项链。

于是妞妞决定自己来制作一条美丽的项链。一条美丽的项链需要满足以下条件:

1、需要使用n种特定的水晶宝珠

2、第i种水晶宝珠的数量不能少于li颗, 也不能多于ri

3、一条美丽的项链由m颗宝珠组成

妞妞意识到满足条件的项链种数可能会很多, 所以希望你来帮助她计算一共有多少种制作美丽的项链的方案。

输入描述:

输入包括n+1行, 第一行包括两个正整数(1 <= n <= 20, 1 <= m <= 100), 表示水晶宝珠的种数和一条美丽的项链需要的水晶宝珠的数量。

接下来的n行, 每行两个整数li, ri(0 <= li <= ri <= 10), 表示第i种宝珠的数量限制区间。

输出描述:

输出一个整数, 表示满足限定条件的方案数。保证答案在64位整数范围内。

输入例子1:

3 5
0 3
0 3
0 3

输出例子1:

12
【分析】: 首先为了方便,在输入的时候,将 [li,ri] 的区间缩小为 [0,ri-li] 。
使用动态规划,DP[i][j]为用前i+1种珠宝制作数量为j的项链的方案数量。
DP[i][j+k]=DP[i-1][j],其中k属于 [0,ri-li]。 可以通过母函数求解。
比较直接的就直接用背包dp算就行了。
【代码】:
#include <iostream>
#include <cstring>
using namespace std;
int main() {
int n, m;
cin >> n >> m;
int *R = new int[n], temp;
for (int i = ; i < n; i++) {
cin >> temp >> R[i];
R[i] -= temp;
m -= temp;
}
long long int **DP = new long long int*[n];
for (int i = ; i < n; i++) {
DP[i] = new long long int[m + ];
memset(DP[i], , sizeof(long long int)*(m + ));
}
for (int i = ; i <= R[]; i++) {
DP[][i] = ;
}
for (int i = ; i < n; i++) {
for (int j = ; j <= R[i]; j++) {
for (int k = ; k <= m - j; k++) {
DP[i][k + j] += DP[i - ][k];
}
}
}
cout << DP[n - ][m] << endl;
delete[] R;
for (int i = ; i < n; i++) {
delete[] DP[i];
}
delete[] DP;
return ;
}

DP

作者:NotDeep
链接:https://www.nowcoder.com/discuss/65411
来源:牛客网 #include <bits/stdc++.h>
using namespace std; long long f[][]; int main() {
int n, m;
scanf("%d%d", &n, &m);
memset(f, , sizeof(f));
f[][] = ;
for (int i = ; i <= n; i++) {
memset(f[i & ], , sizeof(f[i & ]));
int l, r;
scanf("%d%d", &l, &r);
for (int k = l; k <= r; k++)
for (int j = m; j >= k; j--)
f[i & ][j] += f[i + & ][j - k];
}
printf("%lld\n", f[n & ][m]);
return ;
}

母函数

Nowcoder Girl 参考题解【待写】的更多相关文章

  1. Wannafly 挑战赛 19 参考题解

    这一次的 Wannafly 挑战赛题目是我出的,除了第一题,剩余的题目好像对大部分算法竞赛者来说好像都不是特别友好,但是个人感觉题目质量还是过得去的,下面是题目链接以及题解. [题目链接] Wanna ...

  2. 【Luogu】【关卡2-7】深度优先搜索(2017年10月)【AK】【题解没写完】

    任务说明:搜索可以穷举各种情况.很多题目都可以用搜索完成.就算不能,搜索也是骗分神器. P1219 八皇后 直接dfs.对角线怎么判断:同一条对角线的横纵坐标的和或者差相同. #include < ...

  3. 「题解」NOIP模拟测试题解乱写II(36)

    毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...

  4. 「题解」NOIP模拟测试题解乱写I(29-31)

    NOIP模拟29(B) T1爬山 简单题,赛时找到了$O(1)$查询的规律于是切了. 从倍增LCA那里借鉴了一点东西:先将a.b抬到同一高度,然后再一起往上爬.所用的步数$×2$就是了. 抬升到同一高 ...

  5. 关于 OJ1574的参考题解(较麻烦)

    #include <stdio.h>int main(){ long a,b,c,d,e; scanf("%ld",&a); d=a; b=0; while(d ...

  6. 关于 OJ1575的参考题解

    #include <stdio.h>int main(){ int a,b; scanf("%d",&a); b=0; while(a) { b+=a%10; ...

  7. apue编程之参考df代码写的一个简单的df命令的源代码

    代码: #include <stdio.h> #include <mntent.h> #include <string.h> #include <sys/vf ...

  8. LOJ #2533. 「CTSC2018」暴力写挂(边分治合并)

    题意 给你两个有 \(n\) 个点的树 \(T, T'\) ,求一对点对 \((x, y)\) 使得 \[ depth(x) + depth(y) - (depth(LCA(x , y)) + dep ...

  9. HAOI2016 简要题解

    「HAOI2016」食物链 题意 现在给你 \(n\) 个物种和 \(m\) 条能量流动关系,求其中的食物链条数. \(1 \leq n \leq 100000, 0 \leq m \leq 2000 ...

随机推荐

  1. 动态规划、记忆化搜索:HDU1978-How many ways

    Problem Description 这是一个简单的生存游戏,你控制一个机器人从一个棋盘的起始点(1,1)走到棋盘的终点(n,m).游戏的规则描述如下: 1.机器人一开始在棋盘的起始点并有起始点所标 ...

  2. 使用HTTP协议访问网路

    使用HTTP协议访问网路 一.使用HttpURLConnection //new一个URL对象 URL url = new URL("http://www.qq.com");//千 ...

  3. WebView的初体验

    使用安卓自带控件可以实现不通过浏览器即可上网的功能 突然就觉得安卓好强大,是不是我太无知了,太容易满足了 1.在layout中添加VebView控件 2.在Activity中设置WebView的属性 ...

  4. 1 django

    1.MVC 大部分开发语言中都有MVC框架 MVC框架的核心思想是:解耦 降低各功能模块之间的耦合性,方便变更,更容易重构代码,最大程度上实现代码的重用 m表示model,主要用于对数据库层的封装 v ...

  5. IOS笔记050-事件处理

    IOS事件处理 1.触摸事件 2.加速器事件:重力感应,旋转等事件 3.远程遥控事件:蓝牙线控,耳机线控等 触摸事件 响应者对象 只有继承了UIResponder得对象才能接收并处理事件 常见类有:U ...

  6. IOS开发学习笔记029-反选、全选、删除按钮的实现

    还是在上一个程序的基础上进行修改 1.反选按钮 2.全选按钮 3.删除按钮 4.其他代码优化 1.反选按钮 反选的过程就是将_deleteShops数组中得数据清空,然后将Shops中数组添加到_de ...

  7. 07 JVM 是如何实现反射的

    Java 中的反射 反射是 Java 语言的一个相当重要的特性,它允许正在运行的 Java 程序观测,甚至是修改程序的动态行为. 我们可以通过 Class 对象枚举该类中的所有方法,还可以通过 Met ...

  8. Linux下librtmp使用及编程实战

    最近想做rtmp的推流.直播的小项目,不想直接使用FFmpeg进行推流,FFmpeg进行推流特别简单,因为它已经将编码以及librtmp都集成好了,没啥意思.FFmpeg推流的例子,在雷神的博客里可以 ...

  9. maven国内镜像

    <?xml version="1.0" encoding="UTF-8"?> <!--Licensed to the Apache Softw ...

  10. BZOJ 2190:[SDOI2008]仪仗队(欧拉函数)

    [SDOI2008]仪仗队 Description 作为体育委员,C君负责这次运动会仪仗队的训练.仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视 ...