栈
表达式类型题目
先放着
1067
有优先级的括号匹配
用MAP记录和查询优先级
#include <iostream>
#include <string>
#include <string.h>
#include<algorithm>
#include <vector>
#include <map>
#include <stack>
using namespace std;
int main()
{
int n;
string s;
map<char ,int>prior;
prior['{']=4;prior['[']=3;prior['(']=2;prior['<']=1;
while(cin>>n)
{
for(int i=0;i<n;i++)
{
cin>>s;
stack<char>st;
int flag=0;
for(int i=0;i<s.size();i++)
{
if(!st.empty())
{
if(st.top()=='('&&s[i]==')'||st.top()=='['&&s[i]==']'||st.top()=='{'&&s[i]=='}'
||st.top()=='<'&&s[i]=='>')
st.pop();
else
{
if(prior[st.top()]<prior[s[i]])
break;
st.push(s[i]);
}
}
else
st.push(s[i]);
}
if(!st.empty())
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
}
return 0;
}
1296
难
入栈入的是字母标号
#include<iostream>
#include<string>
#include<cstring>
#include<stack>
#include<vector>
using namespace std;
int main() {
string s;
while (cin >> s) {
stack<int> sta;
string str = s;//申请一个与s大小相等字符串空间str
for (int i = 0;i < s.size();i++) {
str[i] = ' ';//把申请的字符串空间str全部置为空格
if (s[i] == '(') {//如果是左括号则直接进栈
sta.push(i);
}
else if (s[i] == ')') {//是右括号看栈是不是空
if (!sta.empty()) {//不空说明栈中有左括号与当前右括号匹配
sta.pop();//把匹配的左括号出栈
}
else if (sta.empty()) {//如果栈空说明没有与之匹配的左括号
str[i] = '?';//需要在str上把相应的位置置为“?”号
}
}
}
while (!sta.empty()) {//判断栈是否为空,不空说明栈中有未匹配完的左括号
str[sta.top()] = '$';//把未匹配的左括号,在str相应位置置为“$”
sta.pop();
}
cout << s << endl << str << endl;//输出s,和str
}
return 0;
}
1501
签到题
1838
签到题
优先队列
就是一个堆,堆顶为优先级最高元素
1544
记录:
1、#include 解决greater报错
2、基本数据类型优先队列写法
详细见算法笔记
#include<iostream>
#include<string>
#include<cstring>
#include<stack>
#include<vector>
#include <queue>
#include <functional>
using namespace std;
int main() {
int n;
priority_queue <int, vector<int>, greater<int> >q;
while(cin>>n)
{
int temp;
for(int i=0;i<n;i++)
{
cin>>temp;
q.push(temp);
}
int result=0;
while(q.size()>1)
{
int temp1=q.top();
q.pop();
int temp2=q.top();
q.pop();
result+=temp1+temp2;
q.push((temp1+temp2));
}
cout<<result<<endl;
}
return 0;
}
二叉树
1109二叉树的建立和遍历
签到题
#include<iostream>
#include<string>
#include<cstring>
#include<stack>
#include<vector>
#include <queue>
#include <functional>
using namespace std;
typedef struct node
{
char date;
struct node *lchild,*rchild;
}*BitTree;//要点1
//创建树
void CreatBitTree(BitTree &T)
{
char c;
cin>>c;
if(c=='0')
T=NULL;
else
{
T =new node;//动态创建结构变量
T->date =c;
CreatBitTree(T->lchild );
CreatBitTree(T->rchild );
}
}
//先序遍历
void PreOrderTraverse(BitTree T)
{
if(T!=NULL)
{
cout<<T->date <<" ";
PreOrderTraverse(T->lchild );
PreOrderTraverse(T->rchild );
}
}
//中序遍历
void InOrderTraverse(BitTree T)
{
if(T!=NULL)
{
InOrderTraverse(T->lchild );
cout<<T->date <<" ";
InOrderTraverse(T->rchild );
}
}
//后序遍历
void PostOrderTraverse(BitTree T)
{
if(T!=NULL)
{
PostOrderTraverse(T->lchild );
PostOrderTraverse(T->rchild );
cout<<T->date <<" ";
}
}
int Leaf(BitTree T)
{
if(T==NULL)return 0;
if(T->lchild ==NULL&&T->rchild ==NULL)return 1;
else
return Leaf (T->lchild )+Leaf (T->rchild );
}
//二叉树的深度
int Deepth(BitTree T)
{
if(T==NULL)return 0;
int x=Deepth (T->lchild );
int y=Deepth (T->rchild );
return max(x,y)+1;
}
int main() {
BitTree T;
CreatBitTree (T);
PreOrderTraverse (T);
cout<<endl;
InOrderTraverse (T);
cout<<endl;
PostOrderTraverse (T);
cout<<endl;
cout<<Leaf (T)<<endl;
system("pause");
return 0;
}
1161
记录:
//原始版本,能通过牛客网,过不了N诺,可能是N诺输入并不默认是正确输入
//通不过的代码,主要是creat_tree部分,写法不一样
#include<iostream>
#include<string>
#include<cstring>
#include<stack>
#include<vector>
#include <queue>
#include <functional>
using namespace std;
string s;
int len=0;
typedef struct node
{
char c;
struct node *lchild,*rchild;
}*tree;
void creat_tree(tree &T)
{
if(len==s.size())
return;
char c=s[len++];
if(c=='#')
T=NULL;
else
{
T=new node;
T->c =c;
creat_tree(T->lchild );
creat_tree(T->rchild );
}
}
void zhongxu(tree T)
{
if(T!=NULL)
{
zhongxu(T->lchild );
cout<<T->c<<" ";
zhongxu(T->rchild );
}
}
int main() {
while(cin>>s)
{
len=0;
tree T;
creat_tree (T);
zhongxu(T);
cout<<endl;
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
typedef struct node{
char data;
struct node *lChild,*rChild;
}*BitTree;
string s1;
int len;
void createTree(BitTree &T){
//字符串为空,或创建完毕的时候
if(len == s1.size())
return;
char c=s1[len++];
if(c=='#'){
T=NULL;
}else{
T=new node;
T->data=c;
T->lChild=NULL;//左右孩子树为空,防止超时
T->rChild=NULL;//
createTree(T->lChild);
createTree(T->rChild);
}
}
void midOrdTrave(BitTree &T){
if(T!=NULL){
midOrdTrave(T->lChild);
cout<<T->data<<" ";
midOrdTrave(T->rChild);
}
}
int main()
{
while(cin>>s1){
len=0;
BitTree T;
createTree(T);
midOrdTrave(T);
cout<<endl;
}
return 0;
}
1233 二叉树
这道题使用的是二叉树的性质,其他没什么
1264
递归终止条件,一般有多种方式:
- 添加递归深度参数到递归函数的参数中
每次调用深度加一,在函数体中添加条件语句,当深度超过某个值时强行return; - 引入元素栈结构,每次递归的一些需要记录的内容,通常会压入栈中,适当的时候再弹出
在函数体中,添加条件语句,判断栈大小或者栈元素,达到条件时进行return;
记录
能不用递归 不用递归
//原始版本,后面编译器又给过了,玄学
#include<iostream>
#include<string>
#include<cstring>
#include<stack>
#include<vector>
#include <queue>
#include <functional>
using namespace std;
void panduan(long long root,long long n,long long &cnt)
{
if(root>n)
{
cnt--;
return;
}
else
{
cnt++;
panduan(root*2,n,cnt);
cnt++;
panduan(root*2+1,n,cnt);
}
return;
}
int main() {
long long m,n;
while(cin>>m>>n)
{
long long temp=1;
if(m==0&&n==0)
continue;
panduan(m,n,temp);
cout<<temp<<endl;
}
system("pause");
return 0;
}
#include<iostream> //完全二叉树顺序存储的遍历,吓唬人的水题
using namespace std;
int m,n,cnt=0;
void DFS(int root){
if(root>n) return;
cnt++;
DFS(root*2);
DFS(root*2+1);
}
int main(){
while(cin >> m >> n){
if(m==0 && n==0) break;
cnt=0;
DFS(m);
cout << cnt << endl;
}
return 0;
}
用队列解决
#include<iostream>
#include<string>
#include<cstring>
#include<stack>
#include<vector>
#include <queue>
#include <functional>
using namespace std;int main(){
int m,n;
queue<int> q;
int sum;
while(scanf("%d %d",&m,&n)!=EOF){
sum = 0;
q.push(m);
while(!q.empty()){
int tmp = q.front();
sum++;
q.pop();
if(2*tmp<=n)
q.push(2*tmp);
if(2*tmp+1<=n)
q.push(2*tmp+1);
}
cout<<sum<<endl;
}
return 0;
}
1401 1561
已知前序和中序求后序
#include <iostream>
#include <string>
#include <string.h>
using namespace std;
void postorder(string preorder ,string midorder)
{
if(preorder.size()==0)
return;
char root=preorder[0];
int index=midorder.find(root);
string preorderleft=preorder.substr(1,index);//下一个前序的左子树
string preorderright=preorder.substr(index+1);//下一个前序的右子树
string midorderleft=midorder.substr(0,index);//下一个中序的左子树
string midorderright=midorder.substr(index+1);//下一个中序的右子树
postorder(preorderleft,midorderleft);
postorder(preorderright,midorderright);
cout<<root;
}
int main()
{
string preorder,midorder;
while(cin>>preorder>>midorder)
{
postorder(preorder ,midorder);
cout<<endl;
}
return 0;
}
1551
简单题
记录
字符串转化为同一个字符的思路值得学
for(int i=0;i<s.size();i++)
if(s[i]!='#')
s[i]='a';
1411 二叉排序树
主要是这段构造代码
void paixu(tree &T,int temp)
{
if(T==NULL)
{
T=new node;
T->data=temp;
T->lchild =NULL;
T->rchild=NULL;
return;
}
else
{
if(temp==T->data)
return;
else if(temp<T->data)
paixu(T->lchild ,temp);
else if(temp>T->data)
paixu(T->rchild ,temp);
}
return;
}
1317 判断两序列是否为同一二叉搜索树序列
之前的思路是求出前序和中序,然后看是否相等
后面发现可以直接比较树,因为已经构建好了树
bool isSamaTree(tree t1, tree t2)
{
if(t1 == NULL && t2 == NULL) return true;
if(t1 == NULL || t2 == NULL) return false;
if(t1->val != t2 ->val) return false;
return isSamaTree(t1->lchild, t2->lchild) && isSamaTree(t1->rchild, t2->rchild);
}
1396
水题
在前面的基础上改改
哈希
1329 1225 1175
水题
1209
这题主要难点是时间限制,所以需要思考其他算法
这个算法很精妙
#include<bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 10;
int f[maxn];
int main() {
int a, b;
while(1) {
scanf("%d%d",&a,&b);
if(a+b==0) break;
f[a]++; f[b+1]--;
}
for(int i=1; i<200000; i++) f[i]+=f[i-1];
while(1) {
scanf("%d%d",&a,&b);
if(a+b==0) break;
for(int i=a;i<=b;i++) printf("%d\n",f[i]);
}
return 0;
}
前缀树
1098
此题较难
由于分支有26个
故采用了 非递归形式
//1161
//通不过的代码,主要是creat_tree部分,写法不一样
#include<iostream>
#include<string>
#include<cstring>
#include<stack>
#include<vector>
#include <queue>
#include <functional>
using namespace std;
const int maxn=26;
typedef struct TrieNode{
int nCount;
struct TrieNode *next[maxn];
}Trie;
Trie root;
void inital()
{
for(int i=0;i<maxn;i++)
root.next [i]=NULL;
}
void creat_tree(string str)
{
int len=str.size();
Trie *p=&root,*q;
for(int i=0;i<len;i++)
{
int k=str[i]-'a';
if(p->next[k]==NULL)
{
q=(Trie*)malloc(sizeof(root));
q->nCount =1;
for(int j=0;j<maxn;j++)
q->next[j]=NULL;
p->next[k] =q;
p=p->next[k];
}
else
{
p->next[k]->nCount ++;
p=p->next [k];
}
}
}
int sum;
//计算叶子结点个数
void couttree()
{
queue <Trie*>q;
q.push(&root);
while(!q.empty())
{
Trie *p=q.front();
q.pop();
int son=0;
for(int i=0;i<maxn;i++)
{
int k=i;
if(p->next[k]==NULL)
son++;
else
q.push(p->next[k]);
}
if(son==maxn) sum+=1;
}
}
int main() {
int n;
while(cin>>n)
{
if(n==0)
break;
string s;
sum=0;
inital();
for(int i=0;i<n;i++)
{
cin>>s;
creat_tree(s);
}
couttree();
cout<<sum<<endl;
}
return 0;
}
用sort 排序
#include<bits/stdc++.h>
using namespace std;
string s[150];
int main()
{
int n;
while (cin>>n,n != 0)
{
int ans = 1;
for (int i = 0; i < n; i++)
cin >> s[i];
sort(s, s + n);
for (int i = 1; i < n; i++)
{
if ((s[i].find(s[i - 1])) != 0)//这步操作可以
ans++;
}
cout << ans << endl;
}
return 0;
}
877

被折叠的 条评论
为什么被折叠?



