目前还是小黄,加油刷,努力变成红名大佬 (2019.4.20)
思路
字符串处理+遍历
实现代码:
#include
#include
#include
#include
#include
using namespace std;
//将输入的字符串进行拆分
void make_input(string& input, vector&vec) {
auto it = input.find(' ');
vec.push_back(input.substr(0, it));
vec.push_back(input.substr(it + 1));
}
void calculate(string& input) {
//空串不处理
if (input.length() == 0) return;
vectorvec;
vectorans;
make_input(input, vec);
int begin = atoi(vec[0].c_str());
int end = atoi(vec[1].c_str());
int temp = 0, sum = 0;
for (int i = begin; i <= end; i++) {
temp = i;
while (temp) {
sum += pow(temp % 10, 3);
temp /= 10;
}
if (sum == i)
ans.push_back(i);
sum = 0;
temp = 0;
}
if (ans.size() == 0) {
cout << "no" << endl;
return;
}
for(int i=0; i
思路:
题目中要求一趟遍历实现删除倒数第n个节点,可以这样:
用两根指针,一根指针fast先走n+1步。如果此时fast指向空节点,则说明待删除节点是头结点,否则第二根slow指针开始遍历链表。
当fast指针遍历到链表尾时,slow指针此时指向的是待删除节点的前驱节点。
实现代码:
class Solution {
public:
ListNode *removeNthFromEnd(ListNode *head, int n) {
if(head==nullptr) return nullptr;
ListNode * fast=head;
ListNode *slow=head;
while(n){
fast=fast->next;
n--;
}
//说明待删除节点是头结点
if (fast == nullptr){
slow = head->next;
return slow;
}
while(fast->next){
slow=slow->next;
fast=fast->next;
}
//删除slow指向的后序节点即可
slow->next=slow->next->next;
return head;
}
};
思路
这种求最优解的,后续结果不影响之前的计算结果的题,就可以用动态规划。粘贴一点我论文里面对于动态规划的讲解:
动态规划算法是求解决策过程最优化的数学方法。解决动态规划问题可以从两方面入手:阶段和决策。
(1)阶段:将原问题的求解过程按照时间或者空间特征来进行分解,依次对每个阶段进行求解,当前阶段的解依赖于之前多阶段的解,但是当前阶段的解无法修改后续阶段的解,即各阶段无后效性。因为一个阶段的解如果存在后效性,则证明此时的阶段划分方法不合理。不断迭代求解各阶段的解,从而获取原问题的最终解。
(2)决策:各阶段在划分之后所采取的动作叫做决策。在实际求解过程中,决策的种类往往在一定范围内。不同的决策往往会影响下一阶段的求解状态。动态规划算法的所有决策应构成最优策略,最优策略的子策略也应该保证其最优性。
对于本题,阶段就是选择了i 个学生,最后一个学生序号为 j 。考察所有的可能情况,情定出 选择学生 j 时数组的极值。
设置一个学生能力值数组stu[j],然后设置二维数组fm[i][j],i表示选取学生的人数,j 表示选取到的最后一人。由于学生的能力值有正有负,因此要用两个数组分别记录选择了 i个学生时,最后一个学生为 j 时,所累积的最大能量值和最小能量值。
那么当状态中其中选择的学生数为 i-1时,依次考察学号为 j-1到 j-d的学生作为学生 j 上一个被选中的学生的情况,记录考察过程中的最大值和最小值,则有状态转移方程:
fm[i][j] = max(fm[i][j], max(fm[i - 1][k] * stu[j], fn[i - 1][k] * stu[j]));
fn[i][j] = min(fn[i][j], min(fm[i - 1][k] * stu[j], fn[i - 1][k] * stu[j]));
再考虑一下边界条件:
实现代码
#include
#include
#include
using namespace std;
void calculate(vector&stu, vector&inf){
vector>fm(inf[0]+1,vector(stu.size()+1));
vector>fn(inf[0]+1,vector(stu.size()+1));
long long ans=0;
//初始化二维数组
for(int i=1; i<=stu.size(); i++){
fm[1][i]=stu[i-1];
fn[1][i]=stu[i-1];
}
for (int j = 1 ; j <= stu.size(); j++) {
for (int i = 2; i <= inf[0]; i++) {
for (int k = j-1; k >= j - inf[1] && k > 0; k--) {
//选择i个学生,第i个学生为j时,当前位置最大值fm[i][j]为
//当前选择学生j以及依次尝试j前的d个学生,选择最大值作为 j 学生前一个学长的学生
fm[i][j] = max(fm[i][j], max(fm[i - 1][k] * stu[j-1], fn[i - 1][k] * stu[j-1]));
fn[i][j] = min(fn[i][j], min(fm[i - 1][k] * stu[j-1], fn[i - 1][k] * stu[j-1]));
}
}
//选择不同学生结尾的,共选取了k个学生的各个结果中的最大值作为最终结果进行输出
ans=max(ans,fm[inf[0]][j]);
}
cout<stu;
vectorinf;
while(cin>>n){
while(n--){
cin>>temp;
stu.push_back(temp);
}
//记录学生数和编号差
cin>>temp>>n;
inf.push_back(temp);
inf.push_back(n);
calculate(stu,inf);
stu.clear();
inf.clear();
}
return 0;
}