目录
字符串二叉排序树
思路
很简单就是在传统二叉排序树的构建过程中略略修改:比较key的过程改为字符串的比较。
然后结点的数据形式变成字符串。最后再加上深度的求解。
直接
代码
#include<iostream>
#include<string>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=1000;
char str[N][N];
struct Node{
char ch[N];
Node *lchild,*rchild;
};
class BST{
private:
Node* root;
public:
void insertBST(Node* &bt,char *s);
void inOrder(Node*bt);
BST(char str[N][N],int length);
Node* getRoot(){return root;}
int getDepth(Node* bt);
};
BST::BST(char str[N][N],int length){
root=NULL;
for(int i=0;i<length;i++){
insertBST(root,str[i]);
}
return;
}
void BST::insertBST(Node* &bt,char *s){
if(bt==NULL){
bt=new Node;
int i,len=strlen(s);
for(i=0;i<len;i++){
bt->ch[i]=s[i];
}
bt->ch[i]='\0';
bt->lchild=NULL;
bt->rchild=NULL;
}
else{
if(strcmp(s,bt->ch)<0) insertBST(bt->lchild,s);
else insertBST(bt->rchild,s);
}
}
void BST::inOrder(Node* bt){
if(bt==NULL) return;
else{
inOrder(bt->lchild);
cout<<bt->ch<<" ";
inOrder(bt->rchild);
}
return;
}
int BST::getDepth(Node* bt){
if(bt->lchild==NULL&&bt->rchild==NULL) return 1;
else{
int l=0,r=0;
if(bt->lchild!=NULL) l=getDepth(bt->lchild);
if(bt->rchild!=NULL) r=getDepth(bt->rchild);
return 1+max(l,r);
}
}
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++){
cin>>str[i];
}
BST bst(str,n);
Node* root=bst.getRoot();
bst.inOrder(root);
cout<<bst.getDepth(root);
return 0;
}
判断栈的输出序列
思路
这题可以看到之前写过的出栈合法性那题的影子。就是模拟,不赘述惹。
直接
代码
#include<iostream>
#include<string>
#include<stack>
using namespace std;
const int N=100;
int a[N],b[N];
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++) cin>>a[i];
for(int i=0;i<n;i++) cin>>b[i];
int ans=0;
stack<int> st;
for(int i=0,k=0;i<n;i++){
st.push(a[i]);
while(!st.empty()&&st.top()==b[k]) k++,st.pop(),ans++;
if(k==n){
cout<<ans;return 0;
}
}
cout<<0;
return 0;
}
已A!
三元组实现对称矩阵相乘
思路
稀疏矩阵压缩那节就提到过,一直没写。今天稍稍写一下吧。
注意是对称的!!
#include<iostream>
using namespace std;
const int N1=35;
const int N2=55;
//矩阵压缩之稀疏矩阵实现矩阵相乘。
struct Tri{
int x;
int y;
int w;
};
int n,num1,num2;
Tri tria[N2],trib[N2];
int getAW(int x,int y){
for(int i=0;i<num1;i++){
if(tria[i].x==x&&tria[i].y==y) return tria[i].w;
}
return 0;
}
int getBW(int x,int y){
for(int i=0;i<num2;i++){
if(trib[i].x==x&&trib[i].y==y) return trib[i].w;
}
return 0;
}
int main(){
cin>>n;
cin>>num1>>num2;
for(int i=0;i<num1;i++) cin>>tria[i].x>>tria[i].y>>tria[i].w;
for(int i=0;i<num2;i++) cin>>trib[i].x>>trib[i].y>>trib[i].w;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
int sum=0;
for(int k=0;k<n;k++){
int a=max(getAW(i,k),getAW(k,i)),b=max(getBW(k,j),getBW(j,k));
sum+=a*b;
}
cout<<sum<<" ";
}
cout<<endl;
}
}
Blah数集(优先队列)
Blah数集
问题分析
暴力?
所谓万物皆可暴力(bushi),我们直接用循环把他前n个数存在一个数组里面然后排个序?
不会分析时间复杂度就很grass了。
(我自己的想法)
找找规律?
(这个图是不是蛮对称的hhhh,或许可以思考下去?)
以1为例。
1的2x+1这一路下去肯定是比3x+1下去要小。
而一次2x+1后的3x+1,与一次3x+1后的2x+1大小不确定,是不是需要比较一下嘞?
同时,先计算出来的数,也会比后面计算出来的数小。(不信你看图)
以上是废话,我自己是这么think了一下的。
key
如果说暴力是全部找出来之后在排序,我们是不是可以想一下有什么可以边找边排序的?
单调栈?单调队列?
好的,已经想到了栈与队列了。
栈先进先出没什么关系,好像。
队列呢?二叉树层序遍历里面不是有一个使用队列的地方吗?
仔细想想好像有一点类似哦,层序遍历是使用一个队列,每输出一个根节点,就将他的左右子树入队。这样就可以保证根节点下一层左边部分的结点先输出了。
那这里呢?
我们是否可以把计算出来的数输出的同时,将他的后续入队,让他后续满足相对较小的先输出呢?
可是怎么区分“2x+1这一路”和“3x+1”?
对的,用两个队列,一个存放2x+1,一个存放3x+1。从起始的值开始入队,利用先进先出的性质。
这里我们就直接可以发现,两个队列是天然的单调队列了。
之前是相对较小,这下只需一步“相对”变“绝对”。
在每次要输出的时候,把两个队列的头头比较,输出那个较小的。
不知道这种带着思考的问题分析效果怎么样,反正我是蛮享受的。找个时间把单调队列的滑动窗口水一下hhhhh
现在应该就有思路了吧,用stl可以,数组模拟队列也可以。
代码
#include<iostream>
using namespace std;
const int N=5e6+10;
int a[N],b[N],h1,t1,h2,t2;
int main(){
int num,n;
while(cin>>num>>n){
h1=1,t1=0,h2=1,t2=0;
int i=0;
while(i<n){
i++;
if(i==n) break;
a[++t1]=num*2+1;
b[++t2]=num*3+1;
if(a[h1]>b[h2]) num=b[h2++];
else if(a[h1]<b[h2]) num=a[h1++];
else{
num=a[h1++];
h2++;
}
}
cout<<num<<endl;
}
return 0;
}
优先队列
#include<iostream>
#include<queue>
using namespace std;
int main(){
int num,n;
while(cin>>num>>n){
priority_queue<int,vector<int>,greater<int> > c;
int i=1;
c.push(num);
while(i<n){
num=c.top();
c.pop();
while(!c.empty()&&c.top()==num) c.pop();
c.push(num*2+1);
c.push(num*3+1);
i++;
}
cout<<c.top()<<endl;
}
return 0;
}
模板生成系统(CCF)
与前端的梦幻联动!hhhhhh
不会写,补正则表达式呜呜呜呜呜呜。
最大字典序
先决知识
字典序是什么
字典序(dictionary order),又称 字母序(alphabetical order),原意是表示英文单词在字典中的先后顺序,在计算机领域中扩展成两个任意字符串的大小关系。
简言之 就是将两个字符串从左到右按照ASCII码比较大小,如果有一方大,他的字典序就大,相同的话继续比较,直到出现不同的字符或者最后两个串相等。
问题分析
我们当然要把最大的那个n放在第一个咯!
那第二个嘞?
首先我们知道,如果要出栈n这个最大的数,就需要先从头扫描,依次入栈,直到我们入栈出栈了n,对吧。
这时候栈可能已经有一定的基础了(栈中有一定的元素了)我们接着怎么比较?
这时候我们就有两种出栈的方式,1.直接弹栈顶 2.看一看后面有没有更大的数可以出栈。
所以
比较这时候的栈顶和后续数的最大那个。看看我们具体该走哪一个方案(我愿称之为试探)
第三个第四个就一次类推
代码
#include<iostream>
#include<stack>
#include<vector>
using namespace std;
const int N=5e4+10;
int q[N];
int n;
vector<int> getResult(){
stack<int> st;
vector<int> ans;
int i=0;
while(q[i]!=n)
st.push(q[i++]);
ans.push_back(q[i++]);
for(;i<n;){
if(!st.empty()){
int a=st.top(),b=q[i],index=b;
for(int j=i;j<n;j++){
if(q[j]>b) b=q[j],index=j;
}
if(b>a) {
while(i!=index) st.push(q[i++]);
ans.push_back(q[i++]);
}
else ans.push_back(a),st.pop();
}
else st.push(q[i++]);
}
while(!st.empty()) ans.push_back(st.top()),st.pop();
return ans;
}
int main(){
stack<int> st;
cin>>n;
for(int i=0;i<n;i++) cin>>q[i];
vector<int> answer=getResult();
for(int i=0;i<n;i++) cout<<answer[i]<<" ";
return 0;
}
嘿嘿~更新了一个高清图~
判断有向图是否是简答无环图
#include<iostream>
using namespace std;
const int N1=25,N2=210;
int numData[N1],arcData[N2][N2];
int num,edge;
int dist[N1],sum;
int main(){
cin>>num>>edge;
for(int i=0;i<edge;i++){
int start,end;
cin>>start>>end;
arcData[start][end]=1;
dist[end]+=1;
}
int visited[N1]={0};
int m=num;
while(m--){
int index;
for(int i=0;i<num;i++){
if(dist[i]==0&&visited[i]==0) {
index=i;
visited[i]=1;
break;
}
}
for(int i=0;i<num;i++){
if(arcData[index][i]==1&&dist[i]!=-1) dist[i]--;
}
}
for(int i=0;i<num;i++) sum+=dist[i];
if(sum==0) cout<<"true";
else cout<<"false";
return 0;
}
这上面这个很明显地复杂了。
我改一改
#include<iostream>
using namespace std;
const int N1=25,N2=210;
int numData[N1],arcData[N2][N2];
int num,edge;
int dist[N1],sum;
int main(){
cin>>num>>edge;
for(int i=0;i<edge;i++){
int start,end;
cin>>start>>end;
arcData[start][end]=1;
dist[end]+=1;
}
int visited[N1]={0};
int m=num;
while(m--){
int index,i=0;
while(dist[i]!=0) i++;
index=i;
if(index==num){
cout<<"false";
return 0;
}
dist[index]=-1;
for(int i=0;i<num;i++){
if(arcData[index][i]==1&&dist[i]!=-1) dist[i]--;
}
}
cout<<"true";
return 0;
}
六度分离(floyd)
这里的样例应该有一点问题,应该输出Yes.
夹带私货:大学的关系就是这么脆弱的嘛,害。
#include<iostream>
using namespace std;
const int N=110;
const int MAXX=99999;
int A[N][N];
int num[N][N];
int n,m;
int main(){
cin>>n>>m;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
A[i][j]=MAXX;
}
}
for(int i=0;i<m;i++){
int x,y;
cin>>x>>y;
A[x][y]=1;
A[y][x]=1;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++) cout<<A[i][j]<<" ";
cout<<endl;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
for(int k=0;k<n;k++){
if(A[j][k]>A[j][i]+A[i][k]&&i!=j&&i!=k&&j!=k){
A[j][k]=A[j][i]+A[i][k];
}
}
}
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++) cout<<A[i][j]<<" ";
cout<<endl;
}
for(int i=0;i<n;i++){
for(int j=0;j<n;j++){
if(num[i][j]>7&&i!=j) {
cout<<"No";
return 0;
}
}
}
cout<<"Yes";
return 0;
}
求连通分量
邻接矩阵直接深搜。
#include<iostream>
using namespace std;
const int N=110;
int n,A[N][N];
int visited[N];
void DFS(int x){
for(int i=0;i<n;i++){
if(A[x][i]==1&&visited[i]==0){
visited[i]=1;
DFS(i);
}
}
}
int main(){
cin>>n;
for(int i=0;i<n;i++){
for(int j=0;j<n;j++) cin>>A[i][j];
}
int ans=0;
while(1){
int sum;
for(int i=0;i<n;i++) sum+=visited[i];
if(sum==n) break;
for(int i=0;i<n;i++){
if(visited[i]==0){
visited[i]=1;
ans++;
DFS(i);
}
}
}
cout<<ans<<endl;
return 0;
}
最小生成树权值之和
最小生成树,我这里用的kruscal。
#include<iostream>
using namespace std;
const int N=25;
struct Edge{
int from,to;
int weight;
};
struct EdgeGraph{
int vextex[N];
Edge edge[N];
int vexNum,edgeNum;
};
int getMin(int TL[],EdgeGraph eg){
int el=0;
int k=0;
int sum=0;
while(el<eg.vexNum-1){
if(TL[eg.edge[k].from]!=TL[eg.edge[k].to]){
int tmp=TL[eg.edge[k].to];
sum+=eg.edge[k].weight;
el++;
for(int i=0;i<eg.vexNum;i++){
if(tmp==TL[i]) TL[i]=TL[eg.edge[k].from];
}
}
k++;
}
return sum;
}
int main(){
EdgeGraph eg;
cin>>eg.vexNum>>eg.edgeNum;
for(int i=0;i<eg.vexNum;i++) eg.vextex[i]=i+1;
//边插边排
cin>>eg.edge[0].from>>eg.edge[0].to>>eg.edge[0].weight;
for(int i=1;i<eg.edgeNum;i++){
Edge g;
cin>>g.from>>g.to>>g.weight;
int j=0;
for(;j<i;j++){
if(eg.edge[j].weight>=g.weight){
for(int k=i-1;k>=j;k--){
eg.edge[k+1]=eg.edge[k];
}
break;
}
}
eg.edge[j]=g;
}
int TL[N];
for(int i=0;i<eg.vexNum;i++) TL[i]=eg.vextex[i];
cout<<getMin(TL,eg)<<endl;
return 0;
}
字符串镜像(栈)
简单的栈的应用!
#include<iostream>
#include<stack>
using namespace std;
const int N=1e5+10;
char st[N];
int tt;
int main(){
int ans=0;
char ch;
cin>>ch;
while(ch!='@'){
if(ch!='&'){
if(tt&&st[tt]==ch) tt--,ans++;
else st[++tt]=ch;
}
cin>>ch;
}
if(tt==0) cout<<ans;
else cout<<"no";
return 0;
}
KMP模板题
模板题,背住
//这是KMP
#include<iostream>
#include<string>
using namespace std;
const int N1=35;
const int N2=15;
string a,b;
void getNext(string b,int *next){
int i=0,j=-1;
next[0]=-1;
int len=b.size();
while(i<len){
if(j==-1||b[i]==b[j]){
i++;
j++;
next[i]=j;
}
else j=next[j];
}
}
bool KMP(string a,string b,int next[]){
int i=0,j=0;
int len=a.size();
while(i<len){
if(j==-1||a[i]==b[j]){
i++;
j++;
}
else j=next[j];
if(j==b.size()) return true;
}
return false;
}
int main(){
cin>>a;
cin>>b;
int next[N2];
getNext(b,next);
cout<<next[0];
for(int i=1;i<b.size();i++) cout<<","<<next[i];
cout<<endl;
if(KMP(a,b,next)) cout<<"YES";
else cout<<"NO";
return 0;
}
火车购票(模拟or队列?)
数组模拟
#include<iostream>
using namespace std;
const int N=110;
int inquire[N];
int seat[20][5];
int main(){
int n;
cin>>n;
for(int i=0;i<n;i++) cin>>inquire[i];
for(int i=0;i<n;i++){
int num=inquire[i];
for(int j=0;j<20;j++){
int sum=0;
for(int k=0;k<5;k++){
sum+=seat[j][k];
}
if(num<=5-sum){
int k=0;
while(seat[j][k]!=0&&k<5) k++;
while(num--){
cout<<j*5+k+1<<" ";
seat[j][k++]=1;
}
num=0;
cout<<endl;
break;
}
}
if(num!=0){
for(int j=1;j<=100;j++){
if(num==0) break;
int x=j/5;
int y=j%5;
if(y==0) x=x-1,y=4;
else y=y-1;
if(seat[x][y]==0){
num--;
seat[x][y]=1;
cout<<j<<" ";
}
}
cout<<endl;
}
}
}
队列怎么做嘞?
坐一个屁股在这。
更新啦
队列
其实也是模拟,只不过有了一个数据结构方便多了!!
#include<iostream>
#include<queue>
using namespace std;
const int N=21;
queue<int> mp[N];
int main(){
int m;
for(int i=0,j=1;i<20;i++){
int cnt=5;
while(cnt--){
mp[i].push(j++);
}
}
cin>>m;
for(int i=0;i<m;i++){
int num;
cin>>num;
bool isLianxu=false;
for(int i=0;i<20;i++){
//可以连续坐
if(mp[i].size()>=num){
isLianxu=true;
for(int j=0;j<num;j++){
cout<<mp[i].front()<<" ";
mp[i].pop();
}
cout<<endl;
break;
}
}
if(!isLianxu){
bool isOk=false;
for(int j=0;j<20&&num>0;j++){
while(!mp[j].empty()&&num>0){
cout<<mp[j].front()<<" ";
mp[j].pop();
num--;
}
}
cout<<endl;
}
}
return 0;
}
二叉树结点(二叉树)
这里的序列不完全,所以只能建树咯
#include<iostream>
using namespace std;
struct Node{
char data;
Node *l,*r;
};
Node* create(Node* bt){
char ch;
cin>>ch;
if(ch=='#') return NULL;
else{
bt=new Node;
bt->data=ch;
bt->l=create(bt->l);
bt->r=create(bt->r);
return bt;
}
}
int num;
void getNum(Node* bt){
if(bt==NULL) return;
if(bt->l==NULL&&bt->r==NULL) num++;
if(bt->l!=NULL) getNum(bt->l);
if(bt->r!=NULL) getNum(bt->r);
}
int main(){
Node* root;
root=create(root);
getNum(root);
cout<<num;
return 0;
}
哈夫曼带权路径
之前有写过这一篇,放个链接http://t.csdn.cn/djJ3W
求后序序列
之前有文章写过。
#include<iostream>
#include<string>
using namespace std;
string a,b;
void build(int l1,int r1,int l2,int r2){
int m=b.find(a[l1]);
if(m>l2) build(l1+1,l1+m-l2,l2,m-1); //左
if(m<r2) build(l1+m-l2+1,r1,m+1,r2); //右
cout<<a[l1];
return;
}
int main(){
cin>>a;
cin>>b;
int m=a.size()-1;
build(0,m,0,m);
return 0;
}
next数组求解
今天我们班一致赞同KMP的题最好做笑死。
大陈曦老师捞人----看破不说破
#include<iostream>
#include<string>
using namespace std;
const int N=110;
string a;
void getNext(string a,int *next){
int i=0,j=-1,len=a.size();
next[0]=-1;
while(i<len){
if(a[i]==a[j]||j==-1){
i++;
j++;
next[i]=j;
}
else j=next[j];
}
}
int main(){
cin>>a;
int next[N];
getNext(a,next);
for(int i=0,len=a.size();i<len;i++) cout<<next[i]<<" ";
return 0;
}
逆序输出中序序列
好吧,又是不得不建树的一道题
挺简单的
#include<iostream>
#include<string>
using namespace std;
string b;
int i;
struct Node{
char data;
Node *l,*r;
};
Node* create(Node* bt){
char ch;
cin>>ch;
if(ch=='#') return NULL;
bt=new Node;
bt->data=ch;
bt->l=create(bt->l);
bt->r=create(bt->r);
return bt;
}
void getInOrder(Node* bt){
if(bt==NULL) return;
getInOrder(bt->l);
b[i++]=bt->data;
getInOrder(bt->r);
return;
}
int main(){
Node* root;
root=create(root);
getInOrder(root);
i--;
while(i>=0){
cout<<b[i--]<<" ";
}
return 0;
}
二叉树的遍历
#include<iostream>
#include<string>
using namespace std;
struct Node{
char data;
Node *l,*r;
};
Node* create(Node* bt){
char ch;
cin>>ch;
if(ch=='#') return NULL;
bt=new Node;
bt->data=ch;
bt->l=create(bt->l);
bt->r=create(bt->r);
return bt;
}
void PreOrder(Node *bt){
if(bt==NULL) return;
cout<<bt->data;
PreOrder(bt->l);
PreOrder(bt->r);
return;
}
void InOrder(Node* bt){
if(bt==NULL) return;
InOrder(bt->l);
cout<<bt->data;
InOrder(bt->r);
return;
}
void PosOrder(Node* bt){
if(bt==NULL) return;
PosOrder(bt->l);
PosOrder(bt->r);
cout<<bt->data;
return;
}
int main(){
Node* root;
root=create(root);
PreOrder(root);
cout<<endl;
InOrder(root);
cout<<endl;
PosOrder(root);
return 0;
}
样例是错的。之前还因为这玩意儿改了好久,以为是自己意识偏差。
计算水坑个数
これはBFSですか?be like迷宫问题?
矩阵最长递增路径
上课
现在你总共有 N 门课需要选择,记为 0 到 N-1。
在选修某些课程之前需要一些先修课程。 例如,想要学习课程 0 ,你需要先完成课程 1 ,我们用一个匹配来表示他们,如: 0,1
给定课程总量,条件条数以及它们的先决条件,判断是否可能完成所有课程的学习?并判断两门课程是先修课程关系?
【输入形式】
第一行,输入:课程数N,课程之间的关系数M
第二行开始,输入M行,输入课程关系(若要学习课程1,需要先完成课程2)输入:课程1,课程2
继续输入两个课程编号c1,c2.
【输出形式】
第一行输出:是否可以完成课程(true/false)
第二行输出:c1是否是c2的先修课程(true/false),如果第一行为false,则不输出第二行。
【样例输入1】
4 4
1,0
2,0
3,1
3,2
3,0
【样例输出1】
true
true
【样例说明1】
总共有 4 门课程。要学习课程 0,你应该先完成课程 1 和课程 2。并且课程 1 和课程 2 都应该排在课程 3之后。这是可能的,因此第一行输出true。3是课程0的先修课程,因此第二行输出true。
【样例输入2】
2 2
1,0
0,1
1,0
【样例输出2】
false
【样例说明2】
总共有 2 门课程。学习课程0之前,你还应先完成课程1;并且学习课程1之前,你需要先完成课程0。这是不可能的,因此第一行输出true。第二行不输出。
简单拓扑拍序+判断无环图。
输入我用string可还行?
//拓扑排序
#include<iostream>
using namespace std;
const int N=110;
int A[N][N],n,m;
int c1,c2,k;
int paixu[N],du[N],visited[N];
int main(){
cin>>n>>m;
for(int i=0;i<m;i++){
string a;
cin>>a;
A[a[0]-'0'][a[2]-'0']=1;
du[a[2]-'0']++;
}
cin>>c1>>c2;
for(int i=0;i<n;i++){
int j;
for(j=0;j<n;j++){
if(du[j]==0&&visited[j]==0) break;
}
if(j==n){
cout<<"false";
return 0;
}
paixu[k++]=j;
visited[j]=1;
for(int a=0;a<n;a++){
if(A[j][a]==1&&du[a]>0) du[a]--;
}
}
cout<<"true"<<endl;
int index1,index2;
for(int i=0;i<n;i++){
if(paixu[i]==c1) index1=i;
if(paixu[i]==c2) index2=i;
}
if(index1<index2){
cout<<"true"<<endl;
}
else cout<<"false"<<endl;
return 0;
}
等待更暖和的一天
【问题描述】
给定每天的温度,求对于每一天需要等几天才可以等到更暖和的一天。如果该天之后不存在
更暖和的天气,则记为 0。天数不超过50天。
【输入形式】
输入是数组长度n和一个一维整数数组
【输出形式】
输出是同样长度的整数数组,表示对于每天需要等待多少天。
【样例输入】
8
73 74 75 71 69 72 76 73
【样例输出】
1 1 4 2 1 1 0 0
【样例说明】
第1天73°,第2天74°,第2天被超过,2-1=1;
第2天74°,第3天75°,第3天被超过,3-2=1;
第3天75°,第7天75°,第7天被超过,7-3=4;
第4天71°,第6天72°,第6天被超过,6-4=2;
...
...
最后两天没有被超越,输出都是0.
【提示】
创建一个单调递减的堆栈,堆栈中栈顶的温度低于栈底,当新出现的温度大于栈顶温度时,持续弹出,直到新温度小于栈顶温度。
实际建立堆栈时,可以压入温度数组的下标,通过下标读取对应的温度,也方便计算日期的差值。
单调栈可以解决问题。看不是很懂他在这里的提示。就先照自己的方式做咯。
其实就是一个求右边最靠近的较大值的下标问题。在加上一点距离的处理。
#include<iostream>
using namespace std;
const int N=110;
int stk[N],tt,n,num[N],ans[N];
int main(){
cin>>n;
int i;
for(i=0;i<n;i++) cin>>num[i];
for(i=n-1;i--;i>=0){
while(tt&&num[stk[tt]]<=num[i]) tt--;
if(!tt) ans[i]=0;
else ans[i]=stk[tt];
stk[++tt]=i;
}
for(int i=0;i<n;i++){
if(ans[i]==0) cout<<0<<" ";
else cout<<ans[i]-i<<" ";
}
return 0;
}
农场主喝水
【问题描述】
农场里有一些奶牛,作为食物的草料不够了。农场主需要去别的农场借草料。该地区有N (2 <= N <= 2,000) 个农场,农场名称用数字N标识,农场之间的道路是双向的,一共有M (1 <= M <= 10,000)条道路,单条长度不超过1,000,000,000里。有一些农场之间有多条道路相连。所有农场都有通路,连接到农场主的农场。农场主的农场是1号农场,他从自己的农场出发,去所有的农场借草料。
农场主需要在路上携带足够的水,假设马跑完一里路需要1盎司的水,在任意一个农场都可以补充水。那么他应该携带一个多大容量的水壶呢?
【输入形式】
第一行输入 N M
下面多行,每一行表示起点农场编号 终点农场编号 路径长度
【输出形式】
水壶的容量,单位为盎司
【样例输入】
3 3
1 2 12
2 3 123
1 3 50
【样例输出】
50
【样例说明】
【评分标准】
帮助退休夫妻找路
【问题描述】
张三和李四夫妇退休后,去国外风景秀美的H市买了一套房子准备安度晚年。住了一段时间后,他们对当地的交通还是不太了解。有时很郁闷,想去一个地方又不知道应该乘什么公交车,在什么地方转车,在什么地方下车。请你写一个程序帮助他用最短的时间到达目的地(假设每一路公交车都只在起点站和终点站停,而且随时都会开)。
【输入形式】
第一行是公交车的总数N(0<=N<=10000);
第二行是张三的所在地start,目的地end;
接着有n行,每行有站名s,站名e,以及从s到e的时间整数t(0<t<100)(每个地名是一个长度不超过30的字符串)。
note:一组数据中地名数不会超过150个。
【输出形式】
如果张三能到达目的地,输出最短的时间;否则,输出“-1”。
【样例输入】
5
Leeds Edinburgh
Glasgow Edinburgh 70
Leeds Glasgow 10
Bristol Edinburgh 40
Leeds Edinburgh 65
Leeds Bristol 20
【样例输出】
60
提示: 时间最短的路径: Leeds -> Bristol ->Edinburgh ,虽然偶尔会迷路,但是因为有了你的帮助 张三和李四从此还是过上了幸福的生活。
――全剧终――
判断是否是镜像二叉树
#include<iostream>
using namespace std;
struct Node{
char data;
Node *lchild,*rchild;
};
Node* create(Node* bt){
char ch;
cin>>ch;
if(ch=='#') return NULL;
bt=new Node;
bt->data=ch;
bt->lchild=create(bt->lchild);
bt->rchild=create(bt->rchild);
return bt;
}
void preOrder(Node* bt){
if(bt==NULL) return;
else{
cout<<bt->data;
preOrder(bt->lchild);
preOrder(bt->rchild);
return;
}
}
bool isSameTree(Node* l,Node* r){
if(l==NULL&&r==NULL) return true;
if(l==NULL||r==NULL) return false;
if(l->data!=r->data) return false;
return isSameTree(l->lchild,r->rchild)&&isSameTree(r->lchild,l->rchild);
}
bool isSymmetric(Node* bt){
if(bt==NULL) return true;
return isSameTree(bt->lchild,bt->rchild);
}
int main(){
Node* root;
root=create(root);
preOrder(root);
cout<<endl;
if(isSymmetric(root)) cout<<"Yes";
else cout<<"No";
return 0;
}