恭喜发现宝藏!微信搜索公众号【TechGuide】关注更多新鲜好文和互联网大厂的笔经面经。
作者@TechGuide【全网同名】
点赞再看,养成习惯,您动动手指对原创作者意义非凡
小美给小团一个n个数字构成的数字序列,问小团能不能经过重新排列后形成1到n的排列。
举例:
小美给小团[2, 1, 3],则可以经过重新排列后构成[1, 2, 3],这是可行的。
小美给小团[4, 4, 1, 3],则无法经过重新排列后构成[1, 2, 3, 4],这是不可行的。
为了防止小团靠运气碰对答案,小美会进行多组询问。
输入描述
第一行是一个数T,表示有T组数据。
对于每组数据:
第一行一个数字n表示小美给出的序列由n个数字构成。
接下来一行n个空格隔开的正整数。
输出描述
对于每组数据,如果可以重新排列后得到1到n的排列,回答一行Yes,如果不可以,回答No
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int a = scanner.nextInt();
List<String> detail = new ArrayList<>();
// 微信关注TechGuide,每天实时更新大厂笔经面经
for (int i = 0;i<a;i++){
boolean flag = true;
int b = scanner.nextInt();
List list = new ArrayList();
for (int j = 0;j<b;j++){
list.add(scanner.nextInt());
}
for (int j = 1;j<b+1;j++){
if (!list.contains(j)){
detail.add("No");
flag = false;
break;
}
}
if (flag) {
detail.add("Yes");
}
}
for (String s : detail){
System.out.println(s);
}
}
}
小美现在有一个字符串,小美现在想知道能不能通过在字符串的尾端增加若干字符使得整个字符串变成一个回文串。
回文串的定义:若一个字符串,对他正序遍历和倒序遍历得到的结果是完全一致的,就称它是一个回文串。例如 abcba 就是一个回文串,因为无论正序还是倒序都是一样的。
对于字符串 abaaca,显然在该字符串末尾继续补上三个字符 aba 就可以构成 abaacaaba,就可以把原字符串变成回文串。换句话说,最少补上三个字符。
你的任务就是找到使得原来的字符串变成回文串所需要的最少字符数量。
输入描述
一行一个字符串,代表小美交给你的字符串。
输出描述
一行一个整数,表示将小美给出的字符串变成回文字符串所需要添补的最少字符数量。
样例输入
abaaca
样例输出
3
思路:暴力即可,从字符串中间开始判断,如果一开始是回文串则不需要补充,否则指针往右移动继续判断,直到找到右侧与左侧满足回文则返回结果。
import java.util.*;
class Solution {
public boolean check(String str, int center, boolean isOdd){
int l = center - 1;
int r = center;
if(isOdd) {
r++;
}
while (r < str.length()) {
if(str.charAt(r) == str.charAt(l)) {
l--;
r++;
}else {
return false;
}
}
return true;
}
}
class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
Solution so = new Solution();
while (in.hasNext()){
String str = in.nextLine();
int center = str.length() / 2;
int res = 0;
boolean isOdd = (str.length() % 2) != 0;
while (!so.check(str, center, isOdd)) {
if(isOdd) {
isOdd = false;
center++;
}else {
isOdd = true;
}
res++;
}
System.out.println(res);
}
}
}
//暴力
// 微信关注TechGuide,每天实时更新大厂笔经面经
#include
using namespace std;
const int maxn=1e3+10;
string s;
int main(){
cin>>s;
int len=s.size();
int flag=0;
int pos=0;
for(int i=(len+1)/2;i<len;i++){
int l=i-1,r=i,jl=i-2,jr=i;
while(r<len&&s[l]==s[r]){
l--;
r++;
}
while(jr<len&&s[jl]==s[jr]){
jl--;
jr++;
}
if(r==len){
if(pos<i){
pos=i;
flag=-1;
}
}
if(jr==len){
if(pos<i-1){
pos=i-1;
flag=1;
}
}
if(flag!=0)break;
}
if(flag==1){
cout<<pos*2+1-len<<endl;
}else if(flag==-1){
cout<<(pos)*2-len<<endl;
}else{
cout<<len-1<<endl;
}
}
class Solution {
public:
int minInsertions(string s) {
int n = s.size();
// 微信关注TechGuide,每天实时更新大厂笔经面经
vector<vector<int>> dp(n, vector<int>(n));
for (int span = 2; span <= n; ++span) {
for (int i = 0; i <= n - span; ++i) {
int j = i + span - 1;
dp[i][j] = min(dp[i + 1][j], dp[i][j - 1]) + 1;
if (s[i] == s[j]) {
dp[i][j] = min(dp[i][j], dp[i + 1][j - 1]);
}
}
}
return dp[0][n - 1];
}
};
小美在数轴上放置了若干个机器人,这些机器人每到整数时刻,就会检查是否和其他机器人重合。如果重合,它就会原地爆炸。
这些机器人的移动速度均为 1 。举例来说,如果一个机器人初始位于点3,然后它的方向是向右的,则时刻1会位于点4,时刻2会位于点5。
小美现在给小团这样一个任务:小美将给出所有机器人的初始位置和初始朝向。小团的任务是判断每个机器人的爆炸时刻。当然,如果有一些机器人永远不会爆炸,则输出-1。
小团向你求助。你能帮帮小团吗?
注意事项1:一个机器人爆炸了之后,就不会再继续存在在这个数轴上。
举例来说,如果有三个机器人,一个位于位置0,向右,一个位于位置2,向右,一个位于位置4,向左。则时刻1的时候,后两个机器人会在位置3相遇并发生爆炸,此后第一个机器人和第三个机器人不会在时刻2继续爆炸(因为此时已经不存在第三个机器人了)
注意事项2:请注意,只有整数时刻机器人才会检查重合。
举例来说,如果有两个机器人,一个位于位置1,向右,一个位于位置2,向左,则它们并不会在整数时刻重合。因此它们两个不存在相遇爆炸。
注意事项3:保证机器人初始时刻不会重叠。换句话说,不存在在时刻0就立刻爆炸的机器人。
输入描述
第一行一个正整数 n 表示有 n 个机器人。
接下来 n 行,每行一个正整数和一个字符,以空格分隔。正整数代表机器人的坐标,字符为大写字母 L 和 R 的其中一个,分别表示机器人向左运动 和 向右运动。
输出描述
输出 n 行,每行一个数字,对应表示每个机器人的答案:
若该机器人会爆炸,输出爆炸时间;若该机器人不会爆炸,输出-1。
样例输入
10
94 R
74 L
90 L
75 R
37 R
99 R
62 R
4 L
92 L
44 R
样例输出
-1
6
23
-1
-1
-1
6
-1
-1
23
三种思路:
import java.util.*;
class Bot{
Boolean isLeft = true;
int seq = 0;
public Bot(boolean isLeft, int seq) {
this.isLeft = isLeft;
this.seq = seq;
}
}
class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int[] nums = new int[n];
Arrays.fill(nums, -1);
Map<Integer, Bot> map = new HashMap<>();
int time = 0;
in.nextLine();
for(int i = 0; i < n; i++) {
String[] str = in.nextLine().split(" ");
boolean isLeft = str[1].equals("L");
map.put(Integer.valueOf(str[0]), new Bot(isLeft, i));
}
while(true) {
// 微信关注TechGuide,每天实时更新大厂笔经面经
int minDis = Integer.MAX_VALUE;
for(Map.Entry<Integer, Bot> bot1 : map.entrySet()) {
for(Map.Entry<Integer, Bot> bot2 : map.entrySet()) {
if(bot1.getKey() != bot2.getKey() && bot1.getValue().isLeft && !bot2.getValue().isLeft
&& bot2.getKey() < bot1.getKey() && (bot1.getKey() - bot2.getKey() + 1) % 2 != 0) {
minDis = Math.min(minDis, bot1.getKey() - bot2.getKey() + 1);
}
}
}
if(minDis == Integer.MAX_VALUE) {
break;
}
int dis = minDis / 2;
time += dis;
Map<Integer, Bot> tmap = new HashMap<>();
for(Map.Entry<Integer, Bot> bot : map.entrySet()) {
int index = bot.getKey();
if(bot.getValue().isLeft) {
index -= dis;
}else {
index += dis;
}
if(tmap.containsKey(index)) {
nums[bot.getValue().seq] = time;
nums[tmap.get(index).seq] = time;
tmap.remove(index);
}else {
tmap.put(index, bot.getValue());
}
}
map = tmap;
}
for(int it : nums) {
System.out.println(it);
}
}
}
#include
#include
#include
#include
#include
using namespace std;
void calc(vector<pair<int, char>> robots){
int n = robots.size();
vector<int> robotsL, robotsR, res(n, -1);
unordered_map<int, int> subs;
for(int i = 0; i < robots.size(); i++) {
subs[robots[i].first] = i;
if(robots[i].second == 'L') robotsL.push_back(robots[i].first);
else robotsR.push_back(robots[i].first);
}
sort(robotsL.begin(), robotsL.end());
sort(robotsR.begin(), robotsR.end());
int i = 0;
// 微信关注TechGUide,每天实时更新大厂笔经面经
while(i < robotsL.size()){
int j = robotsR.size();
while(j > 0){
j--;
if(robotsR[j] > robotsL[i]) continue;
if((robotsL[i] - robotsR[j]) % 2 != 0) continue;
int s = (robotsL[i] - robotsR[j]) / 2;
res[subs[robotsL[i]]] = s;
res[subs[robotsR[j]]] = s;
robotsL.erase(robotsL.begin() + i);
robotsR.erase(robotsR.begin() + j);
i--;
j++;
break;
}
i++;
}
for(int i = 0;i < res.size(); i++){
cout << res[i] << endl;
}
return;
}
int main(){
int n;
cin >> n;
vector<pair<int, char>> robots(n);
for(int i = 0; i < n; i++){
cin >> robots[i].first >> robots[i].second;
}
calc(robots);
return 0;
}
def robotBlast(leftRobot, rightRobot):
# leftRobot为左边的robot, 即向右移动的robot的, rightRobot则为向左移动的robot
n1, n2 = len(leftRobot), len(rightRobot)
if not n1 or not n2:
return [-1 for _ in range(n1 + n2)]
# 降序记录两个能发生爆炸的机器人的下标和爆炸时间
# 微信关注TechGUide,每天实时更新大厂笔经面经
record = []
for idxLeft, posLeft in leftRobot:
for idxRight, posRight in rightRobot:
interval = posRight - posLeft
if interval <= 0 or interval % 2: continue
record.append([idxLeft, idxRight, interval // 2])
record.sort(key=lambda x:x[2], reverse=True)
res = [-1 for _ in range(n1 + n2)]
while record:
left, right, time = record.pop()
res[left] = time
res[right] = time
# 将顶部已经爆炸过的元素给pop出去
while record and (res[record[-1][0]] > 0 or res[record[-1][1]] > 0):
record.pop()
for i in res:
print(i)
小美现在临时接到一个会议通知,需要立刻赶往对应地点开会。
不妨将小美所在的地点抽象成一个图。小美位于节点x的位置,将要赶往节点y开会。
小美启动了打车软件,该打车软件可以将起点定位在任何一个节点开始叫车。但是,叫车是需要时间的,不同位置叫车的等车时间不同。
这就意味着,考虑到叫车的时间,小美可以不选自己所在的节点叫车,而选择一个附近的点叫车,在等车时间内自行走路到对应的节点以缩短综合时间,更快地赶到目的地开会。
请注意:小美的叫车终点只能是开会处,即此题不考虑通过多次打车来缩短时间,只考虑更改起点带来的时间减少。
下面给出一个简单的例子来帮助你理解:
小美位于节点1,开会的地点位于节点3
节点1和节点2之间有一条汽车通行时长为1,步行通行时间为2的通路;
节点2和节点3之间有一条汽车通行时长为2,步行通行时间为5的道路;
节点1的打车等候时间为10,节点2的打车等候时间为1,节点3的打车等候时间为5
此时,显然小美有如下几种方案:
第一种方案:小美在节点1打车,此时小美需要先等时间10上车,之后花费3的时间抵达节点3,共计花费时长13;
第二种方案:小美在节点2打车,此时小美需要步行时长2抵达节点2,此时汽车司机已经等候在节点2,小美直接上车,通行时长2后抵达节点3。共计花费时长为4。
第三种方案:小美直接步行到节点3(因为节点3是开会地点,显然在节点3打车无意义),此时花费的时长为7。
以上三种方案中,应选第二种方案能最快抵达开会地点。共计花费时长为4。
注意:实际打车过程中,司机会存在客人太久没来上车自行取消的可能,这里为了简化问题,我们假设司机耐心是充分的,可以无限制等候乘客。
输入描述
第一行四个正整数n,m,x,y,空格隔开,其中 n 表示点的数量,点的序号依次表示为 1 到 n;m表示边的数量;x表示小美当前的节点位置,y表示小美开会的节点位置。
接下来 m 行,每行四个正整数,空格隔开,x, y, p, q,表示节点 x 和节点 y 之间有一条汽车通行时长 p,步行通行时长 q 的双向道路。
接下来一行 n 个空格隔开的正整数,第 i 个正整数表示在第i个节点打车所需要花费的等车时间。
输出描述
输出一行一个正整数表示小美最快抵达开会地点的时间。
样例输入
3 2 1 3
1 2 1 2
2 3 2 5
10 1 5
样例输出
4
提示
数据范围和说明
对于全体数据保证p和q(即汽车通行时间和步行时间)都是[1, 50]内的正整数,保证每个点打车的等候时间都是[1, 1000]内的正整数
对于n和m,对于60%的数据,保证 1<= n <= 10, 1 <= m <= 30, 对于100%的数据,保证 1<= n <= 50, 1 <= m <= 200,数据保证没有重复的边。
#include
using namespace std;
const int maxn = 1e6+10, inf = 0x3f3f3f3f;
#define int long long
struct edge
{
int v,cost;
edge(int v=0,int c=0):
v(v),cost(c){}
bool operator <(const edge &b)const
{
return cost>b.cost;
}
};
int n,dist1[maxn],dist2[maxn],wait[maxn];
vector<edge> G[maxn];
void dijk(int st,int d[])
{
for(int i=1;i<=n;i++)
d[i]=inf;
d[st]=0;
vector<bool> vis(n+10,false);
priority_queue<edge> pq;
pq.push(edge(st,0));
while(!pq.empty())
{
int x=pq.top().v;
pq.pop();
if(vis[x])
continue;
vis[x]=1;
for(auto &e:G[x])
{
if(!vis[e.v]&&d[e.v]>d[x]+e.cost)
{
d[e.v]=d[x]+e.cost;
pq.push(edge(e.v,d[e.v]));
}
}
}
}
struct rec
{
int u,v,p,q;
rec(){}
rec(int u,int v,int p,int q):
u(u),v(v),p(p),q(q){}
};
/*
* 建立小美到每个节点的最短步行时间
* 建立终点到每个节点的打车时间(不包括叫车时间)
* 关注TechGUide,每天实时更新大厂笔经面经
*/
signed main()
{
std::ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
int m,x,y;
cin>>n>>m>>x>>y;
vector<rec> vec;
for(int i=1;i<=m;i++)
{
int u,v,p,q;
cin>>u>>v>>p>>q;
vec.push_back(rec(u,v,p,q));
G[u].push_back(edge(v,q));
G[v].push_back(edge(u,q));
}
for(int i=1;i<=n;i++)
cin>>wait[i];
dijk(x,dist1);
for(int i=1;i<=n;i++)
G[i].clear();
for(auto &e:vec)
{
G[e.u].push_back(edge(e.v,e.p));
G[e.v].push_back(edge(e.u,e.p));
}
dijk(y,dist2);
int ans=min(dist1[y],wait[x]+dist2[x]);//走到y,直接在x打车
if(x==y)
ans=0;
for(int i=1;i<=n;i++)//x走到i,并打车到y
if(i!=x&&i!=y)
ans=min(ans,max(dist1[i],wait[i])+dist2[i]);
cout<<ans<<endl;
return 0;
}
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class Main {
static List<Load> loads = new ArrayList<>();
static Node[] nodes ;
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int m = scanner.nextInt();
int x = scanner.nextInt();
int y = scanner.nextInt();
nodes= new Node[n+1];
for (int i = 1;i<=m;i++){
Load load = new Load();
load.a = scanner.nextInt();
load.b = scanner.nextInt();
load.car = scanner.nextInt();
load.step = scanner.nextInt();
loads.add(load);
}
for (int i =1;i<=n;i++){
Node node = new Node();
node.index = i;
node.dengche = scanner.nextInt();
nodes[i] = node;
}
for (Load load : loads){
Node head = nodes[load.a];
head.np.add(nodes[load.b]);
Node head1 = nodes[load.b];
head1.np.add(nodes[load.a]);
}
System.out.println(dfs(x,y,0));
}
static int dfs(int x, int y, int time){
// 微信关注TechGuide,每天实时更新大厂笔经面经
if (x == y){
return time;
}
Node head = nodes[x];
List<Node> np = head.np;
List<Integer> buff = new ArrayList<>();
for (Node node : np){
int step = 0;
int car = 0;
for (Load load : loads){
if ((load.a == head.index&&load.b==node.index)||(load.b == head.index&&load.a==node.index)){
step = load.step;
car = load.car;
}
}
if (step !=0) {
//打车 不打车时间比较
buff.add(Math.min(dfs(node.index, y, time + head.dengche + car),dfs(node.index, y, time + step)));
}
buff.add(Integer.MAX_VALUE);
}
int min = Integer.MAX_VALUE;
for (int i : buff){
if (i<min){
min = i;
}
}
return min;
}
static class Load {
int a ;
int b ;
int step;
int car;
}
static class Node{
int index;
int dengche;
List<Node> np = new ArrayList<>();
}
}
小美现在想要经过一个总距离长为n的水洼地。其中一些地块是水坑,另一些是地面。初始的时候小美位于这段水洼地的首个地块的位置。
很显然小美不想自己的鞋湿掉。于是小美想出一个办法:小美每次可以跳到非水坑的地方。不过小美的力气有限,每一步都至多跳距离p。换句话说,小美当前位置在第i个地块上,那么小美下一步可以位于[i+1, i+p]之间的非水坑的地块上。
但小美每跳一步都会消耗力气,跳不同的距离对小美的力气消耗是不同的。
你的任务是帮助小美计算最小的力气消耗,即在保证小美跳到第n个地块的前提下(注意:刚好是第n个地块,本题中不存在n+1之后的地块),求出最少要花费多少力气。
输入描述
第一行两个正整数n和p,空格隔开,n表示地块的数量,p表示小美单次的最远跳跃距离。
接下来一行一个长度为n的字符串,只包含小写字母o和小写字母x,其中小写字母o表示地面,小写字母x表示水坑。保证字符串中的首个字符和末尾字符一定是地面(即小写字母o),保证从起点到终点至少存在一种合法路径。
接下来一行p个正整数,第i个数字表示小美跳跃距离i所需要花费的体力值。(请注意:不保证小美跳的近就一定花费更少的力气)
输出描述
一行一个正整数表示小美最少花费的体力值。
样例输入
10 5
oxxoooxxxo
1 6 9 15 18
样例输出
26
提示
样例解释
地块1 -> 地块4 -> 地块5 -> 地块6 -> 地块10
共计花费力气 9 + 1 + 1 + 15 = 26
数据范围和说明
对于40% 的数据保证 n <= 100, 5 <= p <= 10
对于100%的数据保证 n <= 10,000, 5 <= p <= 100
小美每步跳跃的力气保证是个[1,100]之间的正整数。但不保证跳的越远小美需要消耗的力气越大。
简单dp,dp[i] = Math.min(dp[i], dp[i - dis] + cost[dis]) 其中dp[i]是到i的最小花费,dp[i - dis]表示到达离i距离为dis的点的最小化费,cost[dis]表示跳dis步需要多少花费
import java.util.*;
class Main{
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int p = in.nextInt();
in.nextLine();
char[] path = in.nextLine().toCharArray();
int[] cost = new int[p];
for(int i = 0; i < p; i++) {
cost[i] = in.nextInt();
}
// 微信关注TechGuide,每天实时更新大厂笔经面经
int[] dp = new int[path.length];
Arrays.fill(dp, Integer.MAX_VALUE);
dp[0] = 0;
for(int i = 1; i < path.length; i++) {
if(path[i] != 'x') {
for(int dis = 0; dis < p; dis++) {
int pre = i - dis - 1;
if(pre >= 0 && path[pre] != 'x') {
dp[i] = Math.min(dp[i], dp[pre] + cost[dis]);
}
}
}
}
System.out.println(dp[dp.length - 1]);
}
}
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication
{
class Program
{
static void Main(string[] args)
{
string line;
while ((line = Console.ReadLine()) != null)
{
var info = GetNums(line);
string puddle = Console.ReadLine();
var hp = GetNums(Console.ReadLine());
int minHp = new Solution()
.MinHp(puddle, hp);
Console.WriteLine(minHp);
}
}
static int GetNum(string line)
{
return int.Parse(line);
}
static int[] GetNums(string line)
{
return line
.Split(' ')
.Select(GetNum)
.ToArray();
}
}
class Solution
{
public int MinHp(string puddle, int[] hp)
{
// 微信关注TechGuide,每天实时更新大厂笔经面经
int n = puddle.Length, m = hp.Length;
var dp = new int[n];
for (int i = 1; i < n; i++)
{
dp[i] = 1000001;
}
for (int i = 1; i < n; i++)
{
if (puddle[i] == 'x')
continue;
for (int p = 1; p <= m && i - p >= 0; p++)
{
dp[i] = Math.Min(dp[i], dp[i - p] + hp[p - 1]);
}
}
return dp[n - 1];
}
}
}
恭喜发现宝藏!微信搜索公众号【TechGuide】关注更多新鲜好文和互联网大厂的笔经面经。