A- 幸福列车(HDU 1434)
题解:
用优先队列模拟列车,定义优先级。每辆列车的乘客,先考虑人品值,人品值高的优先级越高;在人品值相同的情况下,(按字典序排序)名字越大的优先级大(strcmp比较)。根据输入的指令再输入指令之后的内容。
#include
#include
#include
#include
#include
#include
struct people
{
char name[20];
int rp;
};
struct cmp
{
bool operator()(people per1,people per2)
{
if (per1.rp==per2.rp)
return strcmp(per1.name,per2.name)<0;
else
return per1.rp>per2.rp;
}
};
using namespace std;
int main()
{
struct people per;
int n,m;
int xi,xj;
char ope[1000];
while(~scanf("%d %d",&n,&m))
{
priority_queue,cmp >q[ 10000+10 ];
for (int i=1; i<=n; i++)
{
scanf("%d",&xi);
for (int j=0; j"%s %d",per.name,&per.rp);
q[i].push(per);
}
}
for (int i=0; i<m; i++)
{
getchar();
scanf("%s",ope);
if (strcmp(ope,"GETOUT")==0)
{
scanf("%d",&xi); //从第Xi辆列车踢出一个人品最差的人
//xi-=1;
if (q[xi].empty()==0)
{
printf("%s\n",q[xi].top().name);
q[xi].pop();
}
}
else if (strcmp(ope,"GETON")==0)
{
scanf("%d %s %d",&xi,per.name,&per.rp); //有一个叫name的人品为RP的人登上第Xi列车
q[xi].push(per);
}
else if (strcmp(ope,"JOIN")==0)
{
scanf("%d %d",&xi,&xj); //将第Xj辆列车合并到Xi辆列车
while (q[xj].empty()==0)
{
q[xi].push( q[xj].top() );
q[xj].pop();
}
}
}
}
return 0;
}
B - 下一较大值(sdut 3332)
题解:
其实这道题用数组模拟更好写些,数据量不太大,两层循环不超时。头铁一下用栈实现,定义两个栈,输入的数不定在两个之间出栈,入栈。
//数组模拟
#include
#include
#include
#include
using namespace std;
const int N=1000+7;
int main()
{
int n,t,a[N],flag;
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
for (int i=0; iscanf("%d",a+i);
for (int i=0; i0;
for (int j=i+1; jif (a[j]>a[i])
{
flag=j;
break;
}
}
printf("%d-->%d\n",a[i],flag?a[flag]:-1);
}
if (t)
puts("");
}
return 0;
}
//栈和队列实现
#include
#include
#include
#include
#include
#include
using namespace std;
int main()
{
int t,n,cmp,flag;
stack<int > s;
stack<int > s1;
int num;
scanf("%d",&t);
while (t--)
{
scanf("%d",&n);
for (int j=0; jscanf("%d",&num);
s.push(num);
}
while (s.empty()==0)
{
flag=0;
while(s.empty()==0)
{
s1.push(s.top());
s.pop();
}
num=s1.top();
s1.pop();
while (s1.empty()==0)
{
cmp=s1.top();
s.push(cmp);
s1.pop();
if (cmp>num&&flag==0)
{
printf("%d-->%d\n",num,cmp);
flag=1;
}
}
if (flag==0)
printf("%d-->-1\n",num);
if (s1.empty()==0)
s1.pop();
}
printf("\n");
}
return 0;
}
C - 行编辑器(SDUT 1479)
题解:
逐个输入字符,判断字符是不是’#’或者’@’,如果是’#’调用出栈函数(调用前判空),如果是’@’,不处理。
#include
#include
#include
#include
#include
#include
using namespace std;
int main()
{
stack<char> s;
stack<char> s1;
char c;
while (~scanf("%c",&c))
{
if (c!='#')
s.push(c);
while(~scanf("%c",&c))
{
if (c==10)//第一个字符是#无效
break;
else if (c=='#')//# 退格符删除一个元素,删除前判空
{
if (s.empty()!=1)
s.pop();
}
else
s.push(c);
}
while (s.empty()==0)
{
c=s.top();
s.pop();
if (c=='@')//如果是@说明之前的字符都被删除了不需要再处理
break;
else
s1.push(c);
}
while (s1.empty()==0)
{
printf("%c",s1.top());
s1.pop();
}
printf("\n");
}
return 0;
}
D - 排队买饭(SDUT 2135)
题解 :
栈和队列模拟,或者数组模拟,数组更简单
//数组模拟,
#include
#include
#include
#include
const int N=10000+50;
using namespace std;
int main()
{
int m,n,a[N],tmp;
char ch[10];
int l,r;
scanf("%d",&m);
for(int i=1;i<=m;i++)
scanf("%d",a+i);
scanf("%d",&n);
l=1,r=m+1;
while(n--)
{
scanf("%s",ch);
if(strcmp(ch,"JOIN")==0)
scanf("%d",&tmp),a[r++]=tmp;
else if(strcmp(ch,"LEAVE")==0)
{
scanf("%d",&tmp);
for(int i=l+tmp-1;i1;i++)
a[i]=a[i+1];
r--;
}
else if(strcmp(ch,"ASK")==0)
{
scanf("%d",&tmp);
printf("%d\n",a[l+tmp-1]);
}
else if(strcmp(ch,"LENGTH")==0)
{
printf("%d\n",r-l);
}
else if(strcmp(ch,"FINISH")==0)
{
scanf("%d",&tmp);
l+=tmp;
}
}
return 0;
}
//栈和队列模拟
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=1000+7;
int main()
{
int m,n,t;
char ope[15];
while(~scanf("%d",&m))
{
stack<int>S;
queue<int>Q;
for (int i=0; iscanf("%d",&t);
Q.push(t);
}
scanf("%d",&n);
while (n--)
{
scanf("%s",ope);
if (strcmp(ope,"JOIN")==0)
{
scanf("%d",&t);
Q.push(t);
}
else if (strcmp(ope,"ASK")==0)
{
scanf("%d",&t);
int len=Q.size();
for (int i=1; i<=len; i++)
{
Q.push(Q.front());
if (i==t)
printf("%d\n",Q.front());
Q.pop();
}
}
else if (strcmp(ope,"LEAVE")==0)
{
scanf("%d",&t);
int len=Q.size();
for (int i=1; i<=len; i++)
{
if (i!=t)
Q.push(Q.front());
Q.pop();
}
}
else if (strcmp(ope,"LENGTH")==0)
{
printf("%d\n",Q.size());
}
else if (strcmp(ope,"FINISH")==0)
{
scanf("%d",&t);
while (!Q.empty()&&t--)
Q.pop();
}
}
}
return 0;
}
E - 回文(SDIBT 2643)
题解:
分别用栈和队列存储字符串,栈和队列同时输出并比较。
#include
#include
#include
#include
using namespace std;
int main()
{
stack<char> s;
queue<char> q;
char c;
int i=0,j;
while(~scanf("%c",&c))
{
if (c==10)
{
break;
}
i++;
s.push(c);
q.push(c);
}
for (j=0; j2; j++)
{
if (q.front()==s.top())
{
q.pop();
s.pop();
}
else
break;
}
if (j==i/2)
printf("是回文\n");
else
printf("不是回文\n");
return 0;
}
F - 出栈序列(SDIBT 2669)
题解:
模拟入栈出栈,后一个出栈数大于前一个出栈数(a[j]>a[j-1])时,说明在出栈之前要先入栈一部分数;当后一个数比前一个数要小时(a[j-1]>a[j]),不需要入栈,直接用栈顶元素与a[j]比较如果相同说明出栈顺序是对的
#include
#include
#include
#include
using namespace std;
const int N=1e4+7;
int main()
{
stack<int > s;
int n,flag;
static int m;
int ord[N];
while (scanf("%d",&n)&&n)
{
flag=1;
for (int i=0; iscanf("%d",ord+i);
//正确的顺序是先把ord[j]入栈。再出栈,省去这两步,直接不入栈了
for (int i=1; i0]; i++)
s.push(i);
m=ord[0];//用于记录入栈入到哪一个数了,不重复入栈或者少入栈
for (int i=1; iif (ord[i]>ord[i-1])
{
for (int j=m+1; jelse
{
if (s.top()!=ord[i])
{
flag=0;
break;
}
else s.pop();
}
}
if (flag==1)
printf("Yes\n");
else
printf("No\n");
}
return 0;
}
G - 括号匹配(SDIBT 2639)
题解:
是左括号进栈,遇到右括号与栈顶元素比较,如果能匹配成功出栈,否则否则无效;如果右括号匹配完毕栈内还有元素,序列无效。
#include
#include
#include
#include
#include
using namespace std;
int main()
{
stack<char > s;
char c,c1;
int flag=1;
while (~scanf("%c",&c))
{
if (c==10)
break;
if (c=='('||c=='['||c=='{'|| c==')'||c==']'||c=='}')
{
if (c=='('||c=='['||c=='{')
s.push(c);
else
{
if (s.empty()==1)
flag=0;
else
{
c1=s.top();
if (c==')')
{
if (c1=='(')
s.pop();
else if (c1!='(')
flag=0;
}
else if (c==']')
{
if (c1=='[')
s.pop();
else
flag=0;
}
else if (c=='}')
{
if (c1=='{')
s.pop();
else
flag=0;
}
}
}
}
if (flag==0)
break;
}
if (flag==0||s.empty()==0)
printf("NO\n");
else
printf("YES\n");
return 0;
}
H- 求子数组的最大和(SDIBT 2650)
题解: 当加到某一个数sum<=0时,sum初始化为0,重新计算。
#include
#include
#include
#include
#include
#include
using namespace std;
int main()
{
int n,m,sum=0;
queue<int> q;
char c;
int i,j;
for ( i=0;; i++)
{
scanf("%d",&n);
q.push(n);
c=getchar();
if (c==10)
break;
}
m=q.front();
for (j=0; jif (j!=0)
sum+=q.front();
q.pop();
if (mif (sum<0)
sum=0;
}
printf("%d\n",m);
return 0;
}
I-Windows Message Queue(zoj 2724)
题意:消息队列是Windows系统的基本基础。对于每个进程,系统都维护一个消息队列。如果此过程发生某些事情,例如鼠标单击,文本更改,系统将向队列添加消息。同时,如果该队列不为空,则该进程将根据优先级值从队列中获取消息。请注意,优先级值较小的意味着优先级越高。指令包括,‘PUT’,’GET’两种,’PUT’:输入一条指令的名字,参数,优先级值,’GET’:输出队列里的所有的消息,如果列表为空输出‘EMPTY QUEUE!’,同一条消息可能出现多次,优先级相同的两条消息,按输入顺序进行输出。指令的个数可能有多条,直到文件结尾。写代码模拟消息队列,
题解: 优先队列模拟。。。。。。
#include
#include
#include
#include
using namespace std;
struct msg
{
char name[10];
int par;
int pri;
};
struct cmp
{
bool operator()(msg a,msg b)
{
return a.pri>b.pri;
}
};
int main()
{
char ord[10];
struct msg me;
priority_queuevector,cmp> q;
while (~scanf("%s",ord))
{
if (strcmp(ord,"PUT")==0)
{
scanf("%s %d %d",me.name,&me.par,&me.pri);
q.push(me);
}
if (strcmp(ord,"GET")==0)
{
if (!q.empty())
{
printf("%s %d\n",q.top().name,q.top().par);
q.pop();
}
else
printf("EMPTY QUEUE!\n");
}
}
return 0;
}
J - 进制转换
题解: 进制转换,C语言入门,用栈比较好些,不用处理下标。
#include
#include
#include
#include
#include
#include
using namespace std;
const int N=1000+7;
int main()
{
int n,r;
while (~scanf("%d %d",&n,&r))
{
int flag=0;
if (n<0)
{
flag=1;
n=-n;
}
stack<char> ss;
while (n)
{
int a=n%r;
//如果a>=10,要用A,B,C...表示
if (a>=10)
a+=55;
else
a+=48;
ss.push(a);
n/=r;
}
if (flag==1)
printf("-");
while (!ss.empty())
{
printf("%c",ss.top());
ss.pop();
}
puts("");
}
return 0;
}