存在n+1个房间,每个房间依次为房间1 2 3...i,每个房间都存在一个传送门,i房间的传送门可以把人传送到房间pi(1<=pi<=i),现在路人甲从房间1开始出发(当前房间1即第一次访问),每次移动他有两种移动策略:
A. 如果访问过当前房间 i 偶数次,那么下一次移动到房间i+1;
B. 如果访问过当前房间 i 奇数次,那么移动到房间pi;
现在路人甲想知道移动到房间n+1一共需要多少次移动;
输入描述:
第一行包括一个数字n(30%数据1<=n<=100,100%数据 1<=n<=1000),表示房间的数量,接下来一行存在n个数字 pi(1<=pi<=i), pi表示从房间i可以传送到房间pi。
输出描述:
输出一行数字,表示最终移动的次数,最终结果需要对1000000007 (10e9 + 7) 取模。
示例1
输入:
2
1 2
复制
输出:
4
复制
说明:
开始从房间1 只访问一次所以只能跳到p1即 房间1, 之后采用策略A跳到房间2,房间2这时访问了一次因此采用策略B跳到房间2,之后采用策略A跳到房间3,因此到达房间3需要 4 步操作。
2.思路与分析:
a.定义dp[i]为第一次到达i天所需要的最少的步数,那么我们要求的便是dp[n+1],数组在这里可以下标1到(n+1)来处理
b.dp[i]=dp[i-1]+1(传送门)+再次来到 i-1 + 1(下一步)
c.如何再次来到 i-1,我们知道回到了那个dp[p[i-1]] (第一次到i-1穿去的那个地方的步数)后访问次数又变奇数了(其他都是偶数,就相当于0),和他第一次从p[i-1]]到第一次到达i-1处一样(此处不用管i-1访问次数,因为我们只需要到达i-1即可,不关心在i-1处下一步的move)
d.dp[i]=dp[i-1]+1(传送门)+ dp[i-1]-dp[p[i-1]]+ 1(下一步)
第二题
https://blog.csdn.net/flushhip/article/details/79458502的题解+下面的代码
#include <bits/stdc++.h>
using namespace std;
int main()
{
long long t,n,k,d1,d2,a,b,c;//注意使用long ling
cin>>t;
while(t--)
{
cin>>n>>k>>d1>>d2;
if(n%3!=0)//三者平衡 不平衡的直接pass
{
cout<<"no"<<endl;
continue;
}
int flag=0;
for(int i=-1;1>=i;i=i+2)//i =-1 和1进行正负d遍历
{
for(int i1=-1;1>=i1;i1=i1+2)//i =-1 和1进行正负d遍历 2*2四种状态
{
long long d11=d1*i;
long long d22=d2*i1;
a=(k-2*d11+d22)/3;
b=(k+d11+d22)/3;
c=(k+d11-2*d22)/3;
if(a+b+c!=k||a<0||b<0||c<0)
{
continue;
}
if(a>n/3||b>n/3||c>n/3)
{
continue;
}
cout<<"yes"<<endl;
flag=1;
break;
}
if(flag==1)break;//一旦找到满足就退出
}
if(flag==0)
cout<<"no"<<endl;;
}
return 0;
}
/*
a = (k-2*d1+d2)/3
b = (k+d1+d2)/3
c = (k+d1-2*d2)/3
*/
有一个仅包含’a’和’b’两种字符的字符串s,长度为n,每次操作可以把一个字符做一次转换(把一个’a’设置为’b’,或者把一个’b’置成’a’);但是操作的次数有上限m,问在有限的操作数范围内,能够得到最大连续的相同字符的子串的长度是多少。
输入描述:
第一行两个整数 n , m (1<=m<=n<=50000),第二行为长度为n且只包含’a’和’b’的字符串s。
输出描述:
输出在操作次数不超过 m 的情况下,能够得到的 最大连续 全’a’子串或全’b’子串的长度。
示例1
输入:
8 1
aabaabaa
复制
输出:
5
复制
说明:
把第一个 ‘b’ 或者第二个 ‘b’ 置成 ‘a’,可得到长度为 5 的全 ‘a’ 子串。
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int len = sc.nextInt();
int oper = sc.nextInt();
String str = sc.next();
System.out.println(windowSolve(str, oper, len));
}
private static int windowSolve(String str, int oper, int len) {
int res=Integer.MIN_VALUE;
int left=0, right=0; // 滑动窗口设置两个指针lr
int an=0, bn=0; //用来计数窗口中a/b的个数
while(right<len){
if(str.charAt(right)=='a') {
an++;
}else {
bn++;
}
// right一直往右走,寻找可行解
if(an<=oper||bn<=oper){
right++;
}else{ // 从可行解中找最优解:left开始往右走
// 此时窗口中已经出现了oper个可以改变的字符,更新结果
res = Math.max(res, right-left);
// left指针往左走,窗口中退出一个字符相应的计数减1,
// 而right指针新指的字符计数已经在刚进入while语句时的if判断已加1
if(str.charAt(left)=='a'){
left++;
an--;
}else{
left++;
bn--;
}
right++;
}
}
res = Math.max(res, right-left);
return res;
}
}
4.以下函数用于将一颗二叉搜索树转换成一个有序的双向链表。要求不能创建任何新的节点,只能调整树种节点指针的指向。
如输入下图中左边的二叉搜索树,则输出转换后的排序双向链表:
10
/ \
6 14
/ \ / \
4 8 12 16
转换成:
4 <=> 6 <=> 8 <=> 10 <=> 12 <=> 14 <=> 16
请指出程序代码中错误的地方(问题不止一处,请尽量找出所有你认为错误的地方):
1 #include
2 using namespace std;
3
4 struct TreeNode {
5 int val;
6 TreeNode *left, *right;
7 };
8
9 TreeNode* Convert(TreeNode* root){
10 if (root == NULL)
11 return root;
12
13 TreeNode* listHead = NULL;
14 TreeNode* listLastNode = NULL;
15
16 stack<TreeNode*> s;
17 while(root){
18 while(root){
19 root=root->left;
20 s.push(root);
21 }
22 root=s.top();
23 s.pop();
24 if (listHead == NULL){
25 listHead = root;
26 }else{
27 listLastNode->right = root;
28 }
29 listLastNode = root;
30 root= root->right;
31 }
32 return listHead;
33 }
你的答案
请指出程序代码中错误的地方(问题不止一处,请尽量找出所有你认为错误的地方):
1 #include
2 using namespace std;
3
4 struct TreeNode {
5 int val;
6 TreeNode *left, *right;
7 };
8
9 TreeNode* Convert(TreeNode* root){
10 if (root == NULL)
11 return root;
12
13 TreeNode* listHead = NULL;
14 TreeNode* listLastNode = NULL;
15
16 stack<TreeNode*> s;
17 while(root){
18 while(root){
s.push(root);
19 root=root->left;
20
21 }
22 root=s.top();
23 s.pop();
24 if (listHead == NULL){
25 listHead = root;
26 }else{
27 listLastNode->right = root;
28 }
29 listLastNode = root;
30 root= root->right;
31 }
32 return listHead;
33 }
TreeNode* Convert(TreeNode* root)
{
if (root == NULL)
return root;
TreeNode* listHead = NULL;
TreeNode* listLastNode = NULL;
stack<TreeNode*> s;
while(root||!s.empty())//
{
while(root!=NULL)
{
s.push(root);//
root=root->left;
}
root=s.top();
s.pop();
if (listHead == NULL)
{
listHead = root;
}
else
{
listLastNode->right = root;
root->left=listLastNode;
}
listLastNode = root;
root= root->right;
}
return listHead;
}