【官方题解】: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。

输入描述:

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

输出描述:

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

输入例子1:

  1. 20

输出例子1:

  1. NGNG
  2.  
  3. 【分析】:仔细观察会发现,每一步的按键方案由奇偶性确定,于是分类确定即可; 也可以用用while实现一个递归。
    【代码】:
  1. #include <bits/stdc++.h>
  2.  
  3. using namespace std;
  4.  
  5. int n;
  6. stack<char> s;
  7. int main() {
  8. cin >> n;
  9. while(n) {
  10. if(n % == ) {
  11. n = (n - ) / ;
  12. s.push('G');
  13. } else {
  14. n = (n - ) / ;
  15. s.push('N');
  16. }
  17. }
  18. while(!s.empty()) {
  19. printf("%c", s.top());
  20. s.pop();
  21. }
  22. printf("\n");
  23. return ;
  24. }

O(logn)/分类讨论

  1. 作者:shiqitao
  2. 链接:https://www.nowcoder.com/discuss/65424?type=0&order=0&pos=6&page=0
  3. 来源:牛客网
  4.  
  5. #include <iostream>
  6. #include <string>
  7. using namespace std;
  8. int main()
  9. {
  10. int n; cin >> n;
  11. string result = "";
  12. while (n != ) {
  13. result = (n % ? "N" : "G") + result;
  14. n = (n - ) / ;
  15. }
  16. cout << result;
  17. return ;
  18. }

递归


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

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

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

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

1

  1. , p

2

  1. , p

3

  1. ,...,p

n

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

输出描述:

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

数论、错排

  1. 作者:shiqitao
  2. 链接:https://www.nowcoder.com/discuss/65424?type=0&order=0&pos=6&page=0
  3. 来源:牛客网
  4.  
  5. #include <iostream>
  6. using namespace std;
  7. int main()
  8. {
  9. int n; cin >> n;
  10. int equal = , count = , data;
  11. while (count < n) {
  12. cin >> data;
  13. if (data == ++count) {
  14. if (count != n) cin >> data;
  15. count++; equal++;
  16. }
  17. }
  18. cout << equal;
  19. return ;
  20. }

Code2


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

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

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

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

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

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

输入描述:

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

输出描述:

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

输入例子1:

  1. 5 9
  2. 4 1 3 5 4

输出例子1:

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

简单遍历一下

  1. 作者:NotDeep
  2. 链接:https://www.nowcoder.com/discuss/65411
  3. 来源:牛客网
  4.  
  5. #include <bits/stdc++.h>
  6.  
  7. using namespace std;
  8.  
  9. int n, s, p[];
  10. int main() {
  11. scanf("%d%d", &n, &s);
  12. for(int i = ; i < n; i++) scanf("%d", &p[i]);
  13. int ans = ;
  14. for (int x = ; x < ( << n); x++) {
  15. int mi = ;
  16. int sum = ;
  17. int cnt = ;
  18. for (int i = ; i < n; i++) {
  19. if ((x & ( << i)) != ) {
  20. mi = min(mi, p[i]);
  21. sum += p[i];
  22. cnt++;
  23. }
  24. }
  25. if (sum >= s && sum - mi < s) {
  26. ans = max(ans, cnt);
  27. }
  28. }
  29. cout << ans << endl;
  30.  
  31. }

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. 输出一个整数,表示妞妞最多能增加的战斗力。

输入例子1:

  1. 4 2
  2. 30 30 30 30 0
  3. 50 0 0 0 0
  4. 0 50 0 50 10
  5. 0 0 50 0 20

输出例子1:

  1. 170

例子说明1:

  1. 妞妞要从4件装备中选取2件, 如果妞妞选择第1件和第3件装备,那么增加的战斗力为30 + 50 + 30 + 50 + 10 = 170, 这是最大的方案。
  2.  
  3. 【分析】:没有想到好办法,m大于等于5时取各个属性的最大值,m小于等于3时遍历,m等于4时为防止超时,用一点小小的技巧即可通过。
    k >= 5的时,每一维属性都取最大求和即可。
    对于k < 5的时,预处理31种情况可能得到的最大的和。然后dfs枚举子集维护最大的答案即可。
    【代码】:
  1. 作者:shiqitao
  2. 链接:https://www.nowcoder.com/discuss/65424?type=0&order=0&pos=6&page=0
  3. 来源:牛客网
  4.  
  5. #include <iostream>
  6. #include <algorithm>
  7. using namespace std;
  8. int main()
  9. {
  10. int n, m; cin >> n >> m;
  11. int **r = new int*[n], result = ;
  12. int maxr[] = { };
  13. for (int i = ; i < n; i++) {
  14. r[i] = new int[];
  15. for (int j = ; j < ; j++) {
  16. cin >> r[i][j];
  17. maxr[j] = max(maxr[j], r[i][j]);
  18. }
  19. }
  20. if (m == ) {
  21. for (int i = ; i < n; i++) {
  22. int temp = ;
  23. for (int k = ; k < ; k++) {
  24. temp += r[i][k];
  25. }
  26. result = max(result, temp);
  27. }
  28. }
  29. else if (m == ) {
  30. for (int i = ; i < n; i++) {
  31. for (int j = ; j < n; j++) {
  32. int temp = ;
  33. for (int k = ; k < ; k++) {
  34. temp += max(r[i][k], r[j][k]);
  35. }
  36. result = max(result, temp);
  37. }
  38. }
  39. }
  40. else if (m == ) {
  41. for (int i = ; i < n; i++) {
  42. for (int j = ; j < n; j++) {
  43. for (int p = ; p < n; p++) {
  44. int temp = ;
  45. for (int k = ; k < ; k++) {
  46. temp += max(max(r[i][k], r[j][k]), r[p][k]);
  47. }
  48. result = max(result, temp);
  49. }
  50. }
  51. }
  52. }
  53. else if (m == ) {
  54. int maxtemp[][] = { };
  55. for (int p = ; p < ; p++) {
  56. for (int q = p + ; q < ; q++) {
  57. int temp = ;
  58. for (int i = ; i < n; i++) {
  59. temp = max(temp, r[i][p] + r[i][q]);
  60. }
  61. for (int k = ; k < ; k++) {
  62. if (k != p && k != q) {
  63. temp += maxr[k];
  64. }
  65. }
  66. result = max(result, temp);
  67. }
  68. }
  69. }
  70. else {
  71. for (int k = ; k < ; k++) {
  72. result += maxr[k];
  73. }
  74. }
  75. cout << result;
  76. return ;
  77. }

冗长

  1. 作者:NotDeep
  2. 链接:https://www.nowcoder.com/discuss/65411
  3. 来源:牛客网
  4.  
  5. #include <bits/stdc++.h>
  6.  
  7. using namespace std;
  8.  
  9. const int maxn = 1e4 + ;
  10.  
  11. int mx[];
  12. int num[maxn][];
  13. int N, K;
  14. int sta[];
  15. int dfs(int s, int cur) {
  16. if(cur == K) return ;
  17. int tmp = ;
  18. for(int i = s; i; i = (i - ) & s) tmp = max(tmp, sta[i] + dfs(s ^ i, cur + ));
  19. return tmp;
  20. }
  21. int main() {
  22. scanf("%d%d", &N, &K);
  23. memset(sta, , sizeof(sta));
  24. memset(mx, , sizeof(mx));
  25. for(int i = ; i < N; i++) {
  26. for(int j = ; j < ; j++) {
  27. scanf("%d", &num[i][j]);
  28. mx[j] = max(mx[j], num[i][j]);
  29. }
  30. for(int j = ; j < ; j++) {
  31. int res = ;
  32. for(int k = ; k < ; k++) {
  33. if(j & ( << k)) {
  34. res += num[i][k];
  35. }
  36. }
  37. sta[j] = max(sta[j], res);
  38. }
  39. }
  40. if(K >= ) {
  41. int ans = ;
  42. for(int i = ; i < ; i++) ans += mx[i];
  43. printf("%d\n", ans);
  44. } else {
  45. printf("%d\n", dfs(, ));
  46. }
  47. return ;
  48. }

DFS


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

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

输入描述:

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

输出描述:

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

输入例子1:

  1. 10

输出例子1:

  1. 9

【分析】:

  1. #include <iostream>
  2. #include <cmath>
  3. using namespace std;
  4. int main()
  5. {
  6. int n; cin >> n;
  7. cout << (int)sqrt(n)*(int)sqrt(n) << endl;
  8. return ;
  9. }
  10.  
  11. //////////////////////////////
  12. #include <bits/stdc++.h>
  13. using namespace std;
  14.  
  15. int n;
  16. int main() {
  17. cin >> n;
  18. int ans = ;
  19. for(int i = ; i <= sqrt(n); i++) ans = i * i;
  20. printf("%d\n",ans);
  21. return ;
  22. }

妞妞参加了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种宝珠的数量限制区间。

输出描述:

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

输入例子1:

  1. 3 5
  2. 0 3
  3. 0 3
  4. 0 3

输出例子1:

  1. 12
    【分析】:
  2.  
  3. 首先为了方便,在输入的时候,将 [li,ri] 的区间缩小为 [0,ri-li]
    使用动态规划,DP[i][j]为用前i+1种珠宝制作数量为j的项链的方案数量。
    DP[i][j+k]=DP[i-1][j],其中k属于 [0,ri-li]。
  4.  
  5. 可以通过母函数求解。
    比较直接的就直接用背包dp算就行了。
    【代码】:
  1. #include <iostream>
  2. #include <cstring>
  3. using namespace std;
  4. int main() {
  5. int n, m;
  6. cin >> n >> m;
  7. int *R = new int[n], temp;
  8. for (int i = ; i < n; i++) {
  9. cin >> temp >> R[i];
  10. R[i] -= temp;
  11. m -= temp;
  12. }
  13. long long int **DP = new long long int*[n];
  14. for (int i = ; i < n; i++) {
  15. DP[i] = new long long int[m + ];
  16. memset(DP[i], , sizeof(long long int)*(m + ));
  17. }
  18. for (int i = ; i <= R[]; i++) {
  19. DP[][i] = ;
  20. }
  21. for (int i = ; i < n; i++) {
  22. for (int j = ; j <= R[i]; j++) {
  23. for (int k = ; k <= m - j; k++) {
  24. DP[i][k + j] += DP[i - ][k];
  25. }
  26. }
  27. }
  28. cout << DP[n - ][m] << endl;
  29. delete[] R;
  30. for (int i = ; i < n; i++) {
  31. delete[] DP[i];
  32. }
  33. delete[] DP;
  34. return ;
  35. }

DP

  1. 作者:NotDeep
  2. 链接:https://www.nowcoder.com/discuss/65411
  3. 来源:牛客网
  4.  
  5. #include <bits/stdc++.h>
  6. using namespace std;
  7.  
  8. long long f[][];
  9.  
  10. int main() {
  11. int n, m;
  12. scanf("%d%d", &n, &m);
  13. memset(f, , sizeof(f));
  14. f[][] = ;
  15. for (int i = ; i <= n; i++) {
  16. memset(f[i & ], , sizeof(f[i & ]));
  17. int l, r;
  18. scanf("%d%d", &l, &r);
  19. for (int k = l; k <= r; k++)
  20. for (int j = m; j >= k; j--)
  21. f[i & ][j] += f[i + & ][j - k];
  22. }
  23. printf("%lld\n", f[n & ][m]);
  24. return ;
  25. }

母函数

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. Unable to execute dex: Multiple dex files define Lcom/myapp/R$array;

    Unable to execute dex: Multiple dex files define Lcom/myapp/R$array; 我这个问题最后解决方式是,吧工程里面用同一个v4包. 很明显, ...

  2. MySQL基础4-SQL简单查询(单表)

    1.SELECT语句 2.运算符的优先级 利用Navicat中的查询方法: 栗子1:查询所有货品信息 栗子2:查询所有货品的id,productName,salePrice 当查询错误的时候出现的界面 ...

  3. 【IPv6】ISATAP隧道技术详解

    一.基本概念       ISATAP(Intra-SiteAutomatic Tunnel Addressing Protocol)    ISATAP是一种非常容易部署和使用的IPv6过渡机制.在 ...

  4. PHP 如何在txt里查找包含某个字符串的那一行?

    <?php $handler=fopen("1.txt","r"); while(!feof($handler)) { $m = fgets($handl ...

  5. PHP 获取上一个页面的url

    php $_SERVER["HTTP_REFERER"]变量可以获取上一个或前一个页面的URL地址. 比如有一个a.php页面,这个页面上有一个链接指向b.php页面,如果我们在a ...

  6. 数组线性表ArrayList 和链表类LinkedList

    数组线性表类ArrayList 和链表类LinkedList 是实现List接口的两个具体类.ArrayList 数组储存元素,这个数组是动态创建的.如果元素个数超过了数组的容量,就创建一个更大的新数 ...

  7. java HashMap HashSet的存储方式

    今天遇到一个bug,简单的说就是把自定义对象作为key 存到HashMap中之后,经过一系列操作(没有remove操作)之后 用该对象到map中取,返回null. 然后查看了HashMap的源代码,g ...

  8. [SPOJ839]Optimal Marks

    [SPOJ839]Optimal Marks 试题描述 You are given an undirected graph \(G(V, E)\). Each vertex has a mark wh ...

  9. 亚瑟王(arthur)

    亚瑟王(arthur) 题目描述 小K不慎被LL邪教洗脑了,洗脑程度深到他甚至想要从亚瑟王邪教中脱坑.他决定,在脱坑之前,最后再来打一盘亚瑟王.既然是最后一战,就一定要打得漂亮.众所周知,亚瑟王是一个 ...

  10. BZOJ 3940: [Usaco2015 Feb]Censoring

    3940: [Usaco2015 Feb]Censoring Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 367  Solved: 173[Subm ...