2022-01-13每日刷题打卡
飞书——每日一题
678. 有效的括号字符串
给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:
任何左括号 ( 必须有相应的右括号 )。
任何右括号 ) 必须有相应的左括号 ( 。
左括号 ( 必须在对应的右括号之前 )。
- 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
一个空字符串也被视为有效字符串。
示例 1:
输入: “()”
输出: True
准备两个栈,一个存左括号的sta,一个存星号的star,注意,这里的栈要存的是int类型而不是char类型,我们把它们在字符串中对应的下标存入栈中,遍历字符串s,遇到左括号便把下标入sta栈,遇到星号便把下标入star栈,遇到右括号,判断sta是否为空,不为空就把sta栈顶元素弹出,如果为空,就判断star是否为空,不为空就把star栈顶元素弹出,如果两个都为空,说明不符合,返回false。等字符串遍历完后,判断一下sta是否为空,如果不为空,就再遍历sta,每次对比sta和star的栈顶元素,比较它们的下标,判断是否是star.top()>sta.top(),这也是为什么我们前面说栈不存字符而是它们的下标。举个例子,如果存的是下标,那么就无法比较出星号和左括号谁先谁后,如果是(*的情况那倒也满足,但 *(的情况就不满足了,所以,我们不光是要比较两个字符数量是否能匹配,还要看它们的位置,只有在左括号后面的星号才能和他匹配。所以,如果star栈为空,或者star的栈顶元素下标小于sta的栈顶元素,都要返回false。
如果是sta为空,就返回true。
class Solution {
public:
bool checkValidString(string s) {
stack<int>sta;
stack<int>star;
int n=s.size();
for(int i=0;i<n;i++)
{
char c=s[i];
if(c=='(')sta.push(i);
else if(c==')')
{
if(sta.size())sta.pop();
else if(star.size())star.pop();
else return false;
}
else star.push(i);
}
while(sta.size())
{
if(star.size()&&sta.top()<star.top())
{
sta.pop();
star.pop();
}
else return false;
}
return true;
}
};
AcWing——y总算法课
849. Dijkstra求最短路 I - AcWing题库
给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,所有边权均为正值。
请你求出 1 号点到n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 −1。
输入格式
第一行包含整数 n 和 m。
接下来 m 行每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。
输出格式
输出一个整数,表示 1 号点到 n 号点的最短距离。
如果路径不存在,则输出 −1。
数据范围
1≤n≤500
1≤m≤10^5
图中涉及边长均不超过10000。
输入样例:
3 3
1 2 2
2 3 1
1 3 4
输出样例:
3
#include<iostream>
using namespace std;
#include<string.h>
const int N=510;
int g[N][N],dist[N],n,m;
bool flag[N];
int dijkstra()
{
memset(dist,0x3f,sizeof dist);
dist[1]=0;
for(int i=0;i<n;i++)
{
int t=-1;
for(int j=1;j<=n;j++)
if(!flag[j]&&(t==-1||dist[t]>dist[j]))
t=j;
flag[t]=true;
for(int j=1;j<=n;j++)
{
dist[j]=min(dist[j],g[t][j]+dist[t]);
}
}
if(dist[n]==0x3f3f3f3f)return -1;
return dist[n];
}
int main()
{
cin>>n>>m;
memset(g,0x3f,sizeof g);
int a,b,c;
for(int i=1;i<=m;i++)
{
cin>>a>>b>>c;
g[a][b]=min(g[a][b],c);
}
cout<<dijkstra()<<endl;
return 0;
}
850. Dijkstra求最短路 II - AcWing题库
给定一个 n 个点 m 条边的有向图,图中可能存在重边和自环,所有边权均为非负值。
请你求出 1 号点到 n 号点的最短距离,如果无法从 1 号点走到 n 号点,则输出 −1。
输入格式
第一行包含整数 n 和 m。
接下来 m 行每行包含三个整数 x,y,z,表示存在一条从点 x 到点 y 的有向边,边长为 z。
输出格式
输出一个整数,表示 1 号点到 n 号点的最短距离。
如果路径不存在,则输出 −1。
数据范围
1≤n,m≤1.5×10^5
图中涉及边长均不小于 0,且不超过 10000
输入样例:
3 3
1 2 2
2 3 1
1 3 4
输出样例:
3
#include<iostream>
using namespace std;
#include<queue>
#include<string.h>
const int N=150010;
int idx,w[N],h[N],e[N],ne[N],n,m,dist[N];
bool flag[N];
typedef pair<int,int>PII;
void add(int a,int b,int c)
{
e[idx]=b,w[idx]=c,ne[idx]=h[a],h[a]=idx++;
}
int dijkstra()
{
memset(dist,0x3f,sizeof dist);
dist[1]=0;
priority_queue<PII,vector<PII>,greater<PII>>heap;
heap.push({0,1});
while(heap.size())
{
auto t=heap.top();
heap.pop();
int ver=t.second,distance=t.first;
if(flag[ver])continue;
flag[ver]=true;
for(int i=h[ver];i!=-1;i=ne[i])
{
int j=e[i];
if(dist[j]>distance+w[i])
{
dist[j]=distance+w[i];
heap.push({dist[j],j});
}
}
}
if(dist[n]==0x3f3f3f3f)return -1;
return dist[n];
}
int main()
{
int a,b,c;
memset(h,-1,sizeof h);
cin>>n>>m;
while(m--)
{
cin>>a>>b>>c;
add(a,b,c);
}
cout<<dijkstra()<<endl;
return 0;
}
蓝桥杯——算法提高
高精度加法
问题描述
计算A+B的值。
输入格式
共三行。第一行为两个数N,M。第二行为一个N位数A。第三行为一个M位数B。
输出格式
共一行,为A+B的和。
样例输入
2 3
01
001
样例输出
2
数据规模和约定
N,M<=10000
#include<iostream>
using namespace std;
#include<vector>
vector<int> add(vector<int>&A,vector<int>&B)
{
vector<int>C;
int t=0;
for(int i=0;i<A.size()||i<B.size();i++)
{
if(i<A.size())t+=A[i];
if(i<B.size())t+=B[i];
C.push_back(t%10);
t/=10;
}
if(t)C.push_back(1);
return C;
}
int main()
{
string a,b;
int n,m;
cin>>n>>m;
cin>>a>>b;
vector<int>A,B;
for(int i=a.size()-1;i>=0;i--)A.push_back(a[i]-'0');
for(int i=b.size()-1;i>=0;i--)B.push_back(b[i]-'0');
vector<int>C=add(A,B);
for(int i=C.size()-1;i>=0;i--)cout<<C[i];
return 0;
}