Nowcoder Girl 参考题解【待写】
【官方题解】: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, 听村里的老人牛牛说如果让这个排列变为:
但是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
妞妞最喜欢的数字就是平方数, 妞妞现在给你一个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 参考题解【待写】的更多相关文章
- Wannafly 挑战赛 19 参考题解
这一次的 Wannafly 挑战赛题目是我出的,除了第一题,剩余的题目好像对大部分算法竞赛者来说好像都不是特别友好,但是个人感觉题目质量还是过得去的,下面是题目链接以及题解. [题目链接] Wanna ...
- 【Luogu】【关卡2-7】深度优先搜索(2017年10月)【AK】【题解没写完】
任务说明:搜索可以穷举各种情况.很多题目都可以用搜索完成.就算不能,搜索也是骗分神器. P1219 八皇后 直接dfs.对角线怎么判断:同一条对角线的横纵坐标的和或者差相同. #include < ...
- 「题解」NOIP模拟测试题解乱写II(36)
毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...
- 「题解」NOIP模拟测试题解乱写I(29-31)
NOIP模拟29(B) T1爬山 简单题,赛时找到了$O(1)$查询的规律于是切了. 从倍增LCA那里借鉴了一点东西:先将a.b抬到同一高度,然后再一起往上爬.所用的步数$×2$就是了. 抬升到同一高 ...
- 关于 OJ1574的参考题解(较麻烦)
#include <stdio.h>int main(){ long a,b,c,d,e; scanf("%ld",&a); d=a; b=0; while(d ...
- 关于 OJ1575的参考题解
#include <stdio.h>int main(){ int a,b; scanf("%d",&a); b=0; while(a) { b+=a%10; ...
- apue编程之参考df代码写的一个简单的df命令的源代码
代码: #include <stdio.h> #include <mntent.h> #include <string.h> #include <sys/vf ...
- LOJ #2533. 「CTSC2018」暴力写挂(边分治合并)
题意 给你两个有 \(n\) 个点的树 \(T, T'\) ,求一对点对 \((x, y)\) 使得 \[ depth(x) + depth(y) - (depth(LCA(x , y)) + dep ...
- HAOI2016 简要题解
「HAOI2016」食物链 题意 现在给你 \(n\) 个物种和 \(m\) 条能量流动关系,求其中的食物链条数. \(1 \leq n \leq 100000, 0 \leq m \leq 2000 ...
随机推荐
- 动态规划:HDU1248-钱币兑换问题
解题心得: (青蛙跳台阶:有n阶台阶,青蛙可以一次跳一阶也可以一次跳两阶,问总共有多好中跳法) 1.之前把这个问题的思路弄错了,以为是递推,就像青蛙跳台阶,用斐波那契求解.但是用斐波那契肯定会超范围. ...
- WPF异步回调时回调函数如何获取异步函数产生的变量
有这么一个问题,WPF在使用异步回调的时候,回调函数需要用到异步函数里产生的一个变量,例如异步函数里查询数据库得到了一个DataTable,如何传递给回调函数呢? [方案一]使用全局变量 很容易想到的 ...
- P3116 [USACO15JAN]会议时间Meeting Time
P3116 [USACO15JAN]会议时间Meeting Time 题目描述 Bessie and her sister Elsie want to travel from the barn to ...
- 【bzoj3339】Rmq Problem
[bzoj3339]Rmq Problem Description Input Output Sample Input 7 50 2 1 0 1 3 21 32 31 43 62 7 Sample ...
- S变换
哈哈,这两天在整理时频分析的方法,大部分参考网上写的比较好的资料,浅显易懂,在这谢过各位大神了! 今天准备写下S变换,由于网上资料较少,自己尝试总结下,学的不好,望各位多多指导 由前面的文章可知,傅里 ...
- SVM python小样例
SVM有很多种实现,但是本章只关注其中最流行的一种实现,即序列最小化(SMO)算法在此之后,我们将介绍如何使用一种称为核函数的方式将SVM扩展到更多的数据集上基于最大间隔的分割数据优点:泛化错误率低, ...
- Flask With
- 1、IOS学习计划
2015年12月10日 -- 2015年12月27日(一共3个周末,12个个工作日) 1.斯坦福公开课(IOS7应用开发) 一共18节课程,通过视频和demo建立感觉 2.千峰的OC课程 一共25节课 ...
- Oracle 学习笔记(十)
合并查询 在实际项目开发中经常遇到要合并结果集的情况,可以使用集合操作符:union,union all,intersect,minus.这次笔记学习这几个操作符. [union] 该操作符用于取得两 ...
- 设计模式学习笔记——java中常用的设计模式
单例设计模式(Singleton Pattern) 观察者模式(Observer Pattern) 工厂模式(Factory Pattern) 策略模式(Strategy Pattern) 适配器模式 ...