栈–队列–贪心小练 [Cloned]
专题链接:https://vjudge.net/contest/341486#overview
A - 扩号匹配问题
原题链接:http://bailian.openjudge.cn/practice/3704?lang=en_US
代码:
#include <iostream>
#include<stack>
#include<queue>
#include<algorithm>
#include<string.h>
#include<stdio.h>
using namespace std;
stack<int> S;
char input[105];
char output[105];
int main()
{
while(~scanf("%s",input))
{
int i;
for(i=0;input[i]!=0;i++)
{
if(input[i]=='(')
{
S.push(i);
output[i]=' ';
}
else if(input[i]==')')
{
if(S.empty())
output[i]='?';
else
{
S.pop();
output[i]=' ';
}
}
else
{
output[i]=' ';
}
}
while(!S.empty())
{
output[S.top()]='$';
S.pop();
}
output[i]=0;
puts(input);
puts(output);
}
return 0;
}
B - 士兵队列训练问题
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1276
代码:
#include<stdio.h>
#include<string.h>
int main()
{
int t,n,i;
while(~scanf("%d",&t)) //多组输入
{
while(t--) //t组输入
{
int x=0; //计数器用来记是否为最后一个,如过时换行,不是就打一个空格(格式要求)
int k=1; //用来判断是叫到2的人出列还是3出列,我定义的是k=1时喊二出列,-1时喊三出列
int a[5050]={0}; //定义一个数组存士兵出列情况,判断是否出列,将出列的赋值为1,没出列的赋值为0
scanf("%d",&n);
int cnt=n; //士兵人数
//前三中有点特殊需要单独判断
if(n==1)
{
printf("1\n");continue;
}
else if(n==2)
{
printf("1 2\n");continue;
}
else if(n==3)
{
printf("1 2 3\n");continue;
}
else{
while(1) //定义一个死循环,后面写一个跳出循环的条件就,人数小与等于3
{
x=0;
for(i=1;i<=n;i++)
{
if(k==1) //喊2的时候
{
if(a[i]==0)
{
x++;
}
if(x==2)
{
a[i]=1; //出列士兵记录
cnt--; //士兵人数减一
x=0;
}
}
if(k==-1) //喊3的时候
{
if(a[i]==0)
{
x++;
}
if(x==3)
{
a[i]=1; //出列士兵记录
cnt--; //士兵人数减一
x=0;
}
}
}
k=-k; //题目中说一轮3一轮2,在这是交换
if(cnt<=3) //人数小于等于3时跳出循环
{
break;
}
}
}
x=0;
for(i=1;i<=n;i++)
{
if(a[i]!=1)
{
if(x!=0) // !0时输出空格
printf(" ");
printf("%d",i);
x++;
}
}
printf("\n");
}
}
return 0;
}
C - Train Problem I
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1022
代码:
#include<stdio.h>
#include<stack>
#include<queue>
using namespace std;
char a[1000];
char b[1000];
bool c[1000];
int main()
{
int n,i;
bool flag; //定义一个标记(int型也行因为只用0和1所以定义bool型)
int j,k,l;
while(~scanf("%d",&n)) //多组输入那辆火车
{
stack<char> s; //定义一个栈
flag=0; //标记初值
j=0; //a下标
k=0; //b下标
l=0; //c下标
scanf("%s",a); //进站顺序
scanf("%s",b); //出站顺序
while(1)
{
if(k==n) //当有0辆火车,反回真值并跳出循环
{
flag=1;
break;
}
if(!s.empty()&&s.top()==b[k]) //当栈不为空且栈顶元素和b相同
{
k++; //b的下标+1,判断下一轮直到k==n时
c[l++]=1; //出栈元素记为1
s.pop(); //出栈
}
else
{
if(j<n) //入栈元素小于栈的大小时能入栈
{
s.push(a[j++]); //入栈
c[l++]=0; //入栈元素记为0
}
else
{
flag=0;
break;
}
}
}
if(flag)
{
printf("Yes.\n");
for(i=0; i<2*n; i++)
{
if(c[i])
{
printf("out\n");
}
else
{
printf("in\n");
}
}
printf("FINISH\n");
}
else
{
printf("No.\n");
printf("FINISH\n");
}
}
return 0;
}
D - 队列和栈
原题链接:http://bailian.openjudge.cn/practice/4099?lang=en_US
代码:
#include<stdio.h>
#include<stack>
#include<queue>
#include<string.h>
using namespace std;
char ch[10]; //定义一个字符数组存push和pop
int q[1000]; //存栈内元素
int p[1000]; //存队列内元素
int main()
{
int m,n;
int x,flag; //x为入栈数字,flag为标记,用来标记是否为空栈或空队列
scanf("%d",&m);
getchar();
while(m--)
{
flag=0; //标记初始化
int c=0,d=0; //c和d为计数器,分别为队列和栈的计数
queue<int> a; //定义一个队列
stack<int> b; //定义一个栈
scanf("%d",&n);
getchar();
while(n--)
{
scanf("%s",ch);
if(ch[1]=='u') //看是push还是pop,如果第二个字符为‘u‘就入栈
{
scanf("%d",&x);
a.push(x); //入队列
b.push(x); //入栈
}
if(ch[1]=='o')
{
if(a.empty()||b.empty()) //判断是否为空栈(空队列)如果为空栈还pop就输出error
{
flag=1;
}
else //否则就pop
{
a.pop();
b.pop();
}
}
}
if(flag!=1) //如果不是空栈或空队列
{
while(!a.empty()) //非空就那一个数组存起来
{
p[d]=a.front();
a.pop();
d++;
}
for(int i=0;i<d;i++) //输出队列元素
{
if(i!=d-1)
{
printf("%d ",p[i]);
}
else
{
printf("%d\n",p[i]);
}
}
while(!b.empty()) //非空就那一个数组存起来
{
q[c]=b.top();
b.pop();
c++;
}
for(int i=c-1;i>=0;i--) //输出队列元素,因为栈是先进后出,所以倒序输出
{
if(i!=0)
{
printf("%d ",q[i]);
}
else
{
printf("%d\n",q[i]);
}
}
}
else
{
printf("error\n");
printf("error\n");
}
while(!a.empty()||!b.empty()) //清空队列和栈内元素
{
a.pop();
b.pop();
}
}
return 0;
}
E - Tian Ji – The Horse Racing
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1052
代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
int a[10050]; //田忌的马
int b[10050]; //齐王的马
int main()
{
int n;
while(~scanf("%d",&n))
{
int win=0,lost=0,s=n,e=0;
int sum=0;
if(n==0)
{
break;
}
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
for(int i=0;i<n;i++)
{
scanf("%d",&b[i]);
}
sort(a,a+n);
sort(b,b+n);
for(int i=0;i<n;i++)
{
for(int j=e;j<s;j++)
{
if(a[i]<b[j]) //田忌最慢的马比齐王最慢的慢
{
lost++; //败场加一
s--;
break; //跳出循环再次比较
}
else if(a[i]>b[j]) //田忌最慢的马比齐王最慢的快
{
win++; //胜场加一
e++;
break; //跳出循环再次比较
}
else //田忌最慢的马和齐王最慢的马速度一样
{
if(a[n-1]<b[s-1]) //田忌最好的马速度小于齐王最好的马
{
lost++; //败场加一
s--;
break;
}
else if(a[n-1]==b[s-1])
{
if(a[i]<b[s-1]) //田忌最慢的马和齐王最好的比
{
lost++; //败场加一
s--;
break;
}
else //顶多可以相等大于是不可能了
{
s--;
break;
}
}
else //田忌最好的马比齐王的快
{
win++; //胜场加一
s--;
n--;
i--;
break;
}
}
}
}
sum=(win-lost)*200;
printf("%d\n",sum);
}
return 0;
}
F - FatMouse’ Trade
原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1009
代码:
#include<stdio.h>
#include<algorithm>
using namespace std;
struct node
{
double c;
int a,b;
}v[1005];
bool cmp(node x,node y)
{
return x.c>y.c;
}
int main()
{
int n,m;
while(~scanf("%d %d",&m,&n))
{
double sum=0.0;
if(n==-1&&m==-1)
{
break;
}
for(int i=0;i<n;i++)
{
scanf("%d %d",&v[i].a,&v[i].b);
v[i].c=v[i].a*1.0/v[i].b;
}
sort(v,v+n,cmp);
for(int i=0;i<n;i++)
{
if(m>v[i].b)
{
sum=sum+v[i].a*1.0;
m=m-v[i].b;
}
else
{
sum=sum+v[i].c*m;
break;
}
}
printf("%.3lf\n",sum);
}
return 0;
}
G - Web Navigation
原题链接:http://poj.org/problem?id=1028
代码:
/* 灵活运用string */
#include<cstdio>
#include<cstring>
#include<stack>
#include<iostream>
using namespace std;
stack<string>a;
stack<string>b;
int main()
{
string str;
b.push("http://www.acm.org/");
while(cin>>str&&str!="QUIT")
{
if(str=="VISIT")
{
string str1;
cin>>str1;
while(!a.empty())
{
a.pop();
}
b.push(str1);
cout<<str1<<endl;
}
if(str=="BACK")
{
if(b.size()==1)
{
cout<<"Ignored"<<endl;
}
else
{
a.push(b.top());
b.pop();
cout<<b.top()<<endl;
}
}
if(str=="FORWARD")
{
if(a.empty())
{
cout<<"Ignored"<<endl;
}
else
{
b.push((a.top()));
cout<<a.top()<<endl;
a.pop();
}
}
}
return 0;
}
H - k-rounding
原题链接:https://vjudge.net/problem/CodeForces-858A
代码实现:
/*
给出一个k和一个m,找一个最小的数x,且该数满足x%k==0并且末尾的0的数量大于等于m
只要对k先不停的除5再不停的除2,所得到的结果末尾加上m个0即可
由于数据范围过大所以定义为long long型
*/
#include<cstdio>
#include<iostream>
using namespace std;
int main()
{
long long n,k;
cin>>n>>k;
int x=0,y=0;
while(n%5==0&&x<k)
{
n/=5;
x++;
}
while(n%2==0&&y<k)
{
n/=2;
y++;
}
for(int i=0;i<k;i++)
{
n*=10;
}
cout<<n<<endl;
return 0;
}