目录
问题 A: 数据结构作业02 -- 四则运算表达式计算
大模拟
如果让用python,我直接eval其实思路就是用两个栈,一个存要运算的数,一个存符号,然后碰到优先级高的先计算
这题特判挺多的,主要有这么几个
1,最后一个是(
2,有)而前面没有(的
3,有数字前面没有运算符
4,有运算符前后有一个没数字
5,除数为0
反正是挺难调的
感觉这题,,,,挺晦气的
代码如下
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et cout<<'\n'
#define xx first
#define yy second
using namespace std;
template <typename _Tp>void input(_Tp &x){
char ch(getchar());bool f(false);while(!isdigit(ch))f|=ch==45,ch=getchar();
x=ch&15,ch=getchar();while(isdigit(ch))x=x*10+(ch&15),ch=getchar();
if(f)x=-x;
}
template <typename _Tp,typename... Args>void input(_Tp &t,Args &...args){input(t);input(args...);}
stack<int> num;
stack<char> op;
string str;
map<char,int> pr;
bool eval(){
if (num.empty()){
return false;
}
int b = num.top();
num.pop();
if (num.empty()){
return false;
}
int a = num.top();
num.pop();
int res=0;
if (op.empty()){
return false;
}
char c=op.top();
op.pop();
if (c=='+'){
res=a+b;
}
else if(c=='-'){
res=a-b;
}
else if(c=='/'){
if(b==0) return false;
res=a/b;
}
else res=a*b;
num.push(res);
return true;
}
void ini(){
while(num.size()){
num.pop();
}
while(op.size()){
op.pop();
}
}
void work(){
int n=str.size();
if(str[n-1]=='(') {
cout<<"error\n";
return ;
}
fer(i,0,n-1){
if (isdigit(str[i])) {
int x=0;
int j=i;
while(j<n&&isdigit(str[j])){
x=x*10+str[j++]-'0';
}
num.push(x);
i=j-1;
}
else if(str[i] == '(') {
op.push(str[i]);
}
else if(str[i]== ')') {
if(op.empty()) {
cout<< "error\n";
return ;
}
while(op.top()!='(') {
if (!eval()){
cout<< "error\n";
return ;
}
if(op.empty()){
cout<<"error\n";
return ;
}
}
op.pop();
}
else {
while(op.size()&&pr[op.top()]>=pr[str[i]]){
if(!eval()){
cout<<"error\n";
return ;
}
}
op.push(str[i]);
}
}
while(op.size()){
if(!eval()){
cout<<"error\n";
return ;
}
}
if(num.empty()){
cout<< "error\n";
return ;
}
printf("%lld\n",num.top());
return ;
}
signed main(){
pr['+']=1;
pr['-']=1;
pr['*']=2;
pr['/']=2;
while(cin>>str){
ini();
work();
}
}
问题 B: 栈的操作问题
栈混洗问题
贪心
因为初始序列是1 2 3 4 5,,,
如果前面出现了5,那么小于5的数字顺序其实就已经固定了,因为想要弹出5
1 2 3 4必须入栈
如果到那一步矛盾了就输出error
代码如下:
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et cout<<'\n'
#define xx first
#define yy second
using namespace std;
template <typename _Tp>void input(_Tp &x){
char ch(getchar());bool f(false);while(!isdigit(ch))f|=ch==45,ch=getchar();
x=ch&15,ch=getchar();while(isdigit(ch))x=x*10+(ch&15),ch=getchar();
if(f)x=-x;
}
template <typename _Tp,typename... Args>void input(_Tp &t,Args &...args){input(t);input(args...);}
int a[100000];
signed main(){
int n;
while(cin>>n){
vector<int> s;
s.pb(0);
fer(i,0,n-1){
cin>>a[i];
}
int j=1;
fer(i,0,n-1){
if(a[i]>s.back()){
while(s.back()!=a[i]){
s.pb(j);
cout<<"P";
j++;
}
}
else if(a[i]<s.back()){
cout<<" error";
break;
}
if(a[i]==s.back()){
s.pop_back();
cout<<"Q";
}
}
cout<<'\n';
}
}
问题 C: 杨辉三角
这个格式有点别扭
他的输出要求是这样的
求一下最大位宽是多少
先预处理一下三角
最大数在三角的最后一排的中间
找一下他有多少位就好了
代码如下:
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et cout<<'\n'
#define xx first
#define yy second
using namespace std;
template <typename _Tp>void input(_Tp &x){
char ch(getchar());bool f(false);while(!isdigit(ch))f|=ch==45,ch=getchar();
x=ch&15,ch=getchar();while(isdigit(ch))x=x*10+(ch&15),ch=getchar();
if(f)x=-x;
}
template <typename _Tp,typename... Args>void input(_Tp &t,Args &...args){input(t);input(args...);}
int getwei(int x){
int res=0;
while(x){
res++;
x/=10;
}
return res;
}
int a[100][100];
signed main(){
fer(i,0,40){
a[i][0]=1;
}
fer(i,1,33){
fer(j,1,i){
a[i][j]=a[i-1][j-1]+a[i-1][j];
}
}
int n;
while(cin>>n){
int maxwei=1;
maxwei+=getwei(a[n-1][n/2]);
cout<<"1\n";
fer(i,1,n-1){
cout<<1;
fer(j,1,i){
int weishu=getwei(a[i][j]);
fer(k,1,maxwei-weishu) cout<<" ";
cout<<a[i][j];
}
cout<<'\n';
}
cout<<'\n';
}
}
问题 D: 算法3-1:八进制数
直接除
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et cout<<'\n'
#define xx first
#define yy second
using namespace std;
template <typename _Tp>void input(_Tp &x){
char ch(getchar());bool f(false);while(!isdigit(ch))f|=ch==45,ch=getchar();
x=ch&15,ch=getchar();while(isdigit(ch))x=x*10+(ch&15),ch=getchar();
if(f)x=-x;
}
template <typename _Tp,typename... Args>void input(_Tp &t,Args &...args){input(t);input(args...);}
signed main(){
int n;
while(cin>>n){
vector<int> v;
while(n){
if(n>=8){
v.pb(n%8);
n/=8;
}
else{
v.pb(n);
break;
}
}
reverse(v.begin(),v.end());
for(auto t:v) cout<<t;
cout<<'\n';
}
}
问题 E: 算法3-2:行编辑程序
大模拟
但是比第一题好写
这道题数组实现栈比较好写 退一步直接top--就好了
其他按题的要求写就好
问题不大
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et cout<<'\n'
#define xx first
#define yy second
using namespace std;
template <typename _Tp>void input(_Tp &x){
char ch(getchar());bool f(false);while(!isdigit(ch))f|=ch==45,ch=getchar();
x=ch&15,ch=getchar();while(isdigit(ch))x=x*10+(ch&15),ch=getchar();
if(f)x=-x;
}
template <typename _Tp,typename... Args>void input(_Tp &t,Args &...args){input(t);input(args...);}
const int N=1e6+10;
int top=-1;
char ch;
char a[20000];
void solve(){
ch=getchar();
while(ch!=EOF)
{
while(ch!=EOF&&ch!= '\n')
{
if(ch=='#') top--;
else if(ch=='@') top=-1;
else{
top++;
a[top]=ch;
}
ch=getchar();
}
int i=0;
while(i<=top)
{
cout<<a[i];
i++;
}
top=-1;
cout<<'\n';
if(ch!=EOF){
ch=getchar();
}
}
}
signed main()
{
solve();
}
问题 F: 算法3-3:迷宫
dfs人家都输出最短路径,谁知道他让输出个这东西
主要在于,当他4个方向都走完并且没有走出去时
还是个暴力,又是大模拟
要把此位置设成“!”
还有就是他这个输入真的**,用getchar读空格比较好用
代码如下
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et cout<<'\n'
#define xx first
#define yy second
using namespace std;
template <typename _Tp>void input(_Tp &x){
char ch(getchar());bool f(false);while(!isdigit(ch))f|=ch==45,ch=getchar();
x=ch&15,ch=getchar();while(isdigit(ch))x=x*10+(ch&15),ch=getchar();
if(f)x=-x;
}
template <typename _Tp,typename... Args>void input(_Tp &t,Args &...args){input(t);input(args...);}
char mp[100][100];
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
int dfs(int x,int y){
int nx,ny;
if(mp[x][y]=='E')
{
mp[x][y]='*';
return 1;
}
fer(i,0,3){
nx=dx[i]+x;
ny=dy[i]+y;
if(mp[nx][ny]==' ')
{
mp[nx][ny]='*';
return dfs(nx,ny);
}
else if(mp[nx][ny]=='E')
{
mp[nx][ny]='*';
return 1;
}
}
mp[x][y]='!';
fer(i,0,3){
nx=dx[i]+x;
ny=dy[i]+y;
if(mp[nx][ny]=='*') return dfs(nx,ny);
}
return 1;
}
void solve(){
int x,y;
int q,p;
fer(i,0,9){
fer(j,0,9){
mp[i][j]=getchar();
if(mp[i][j]=='S')
{
x=i;
y=j;
}
if(mp[i][j]=='E')
{
q=i;
p=j;
}
}
getchar();
}
mp[x][y]='*';
dfs(x,y);
if(mp[q][p]!='E')
{
fer(i,0,9){
fer(j,0,9){
cout<<mp[i][j];
}
cout<<'\n';
}
}
else{
fer(i,0,9){
fer(j,0,9){
if(mp[i][j]=='*'){
cout<<"!";
}
else{
cout<<mp[i][j];
}
}
cout<<'\n';
}
}
}
signed main()
{
solve();
}
问题 G: 算法3-5:n阶Hanoi塔问题
经典题:
一定要按他格式输出
就是递归x y z->x z y->y x z的过程
只不过每层要输出一下
代码如下:
#include <bits/stdc++.h>
//#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et cout<<'\n'
#define xx first
#define yy second
using namespace std;
template <typename _Tp>void input(_Tp &x){
char ch(getchar());bool f(false);while(!isdigit(ch))f|=ch==45,ch=getchar();
x=ch&15,ch=getchar();while(isdigit(ch))x=x*10+(ch&15),ch=getchar();
if(f)x=-x;
}
template <typename _Tp,typename... Args>void input(_Tp &t,Args &...args){input(t);input(args...);}
int m=1;
void dfs(char x,int n,char y)
{
printf("%2d. Move disk %d from %c to %c\n",m,n,x,y);
m++;
}
void hanoi(int n,char x,char y,char z)
{
if(n==1)
{
dfs(x,1,z);
}
else{
hanoi(n-1,x,z,y);
dfs(x,n,z);
hanoi(n-1,y,x,z);
}
}
signed main()
{
int n;
while(cin>>n)
{
hanoi(n,'X','Y','Z');
m=1;
cout<<'\n';
}
return 0;
}
问题 H: 算法3-7:银行排队
有n个窗口,给出m个人的到达时间和办理时间
问平均等待时长
暴力就好
每来一个人,扫一遍n个窗口
找出最早工作结束的窗口,然后更新窗口的工作时间
代码如下:
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et cout<<'\n'
#define xx first
#define yy second
using namespace std;
template <typename _Tp>void input(_Tp &x){
char ch(getchar());bool f(false);while(!isdigit(ch))f|=ch==45,ch=getchar();
x=ch&15,ch=getchar();while(isdigit(ch))x=x*10+(ch&15),ch=getchar();
if(f)x=-x;
}
template <typename _Tp,typename... Args>void input(_Tp &t,Args &...args){input(t);input(args...);}
int mp[100000];
int m;
void solve(){
int total;
input(total);
int sum=0;
int k=0;
fer(i,0,m+1) mp[i]=0;
fer(i,0,total-1){
int a,b;
input(a,b);
for(int j=0;j<m;j++){
if(mp[j]<mp[k]){
k=j;
}
}
if(a<=mp[k]){
sum+=(mp[k]-a);
mp[k]+=b;
}
else{
mp[k]=a+b;
}
}
printf("%.2lf\n",((sum*1.0)/(1.0*total)));
}
signed main()
{
while(cin>>m){
solve();
}
}
问题 I: 括号匹配问题
一道经典的栈应用
左括号入栈,右括号可以与栈顶的左括号抵消
看最后栈是否空以及过程中是否有没有左括号可用的情况
代码如下:
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et cout<<'\n'
#define xx first
#define yy second
using namespace std;
template <typename _Tp>void input(_Tp &x){
char ch(getchar());bool f(false);while(!isdigit(ch))f|=ch==45,ch=getchar();
x=ch&15,ch=getchar();while(isdigit(ch))x=x*10+(ch&15),ch=getchar();
if(f)x=-x;
}
template <typename _Tp,typename... Args>void input(_Tp &t,Args &...args){input(t);input(args...);}
string a;
signed main()
{
while(cin>>a){
int flag=0;
vector<char> s;
for(auto t:a)
{
if(t=='('){
s.pb(t);
}
else if(t==')'&&!s.empty()){
s.pop_back();
}
else{
flag=1;
break;
}
}
if(s.size()==0&&flag==0)
{
cout<<"YES"<<'\n';
}
else{
cout<<"NO"<<'\n';
}
}
}
问题 J: 案例3-1.9:银行业务队列简单模拟
题意还是不难理解的
奇数去A,偶数去B
A输出两个B输出一个
并且A先输出
其中一个窗口输出完了,另一个窗口输出
代码如下:
#include <bits/stdc++.h>
#define int long long
#define pb push_back
#define fer(i,a,b) for(int i=a;i<=b;++i)
#define der(i,a,b) for(int i=a;i>=b;--i)
#define all(x) (x).begin(),(x).end()
#define pll pair<int,int>
#define et cout<<'\n'
#define xx first
#define yy second
using namespace std;
template <typename _Tp>void input(_Tp &x){
char ch(getchar());bool f(false);while(!isdigit(ch))f|=ch==45,ch=getchar();
x=ch&15,ch=getchar();while(isdigit(ch))x=x*10+(ch&15),ch=getchar();
if(f)x=-x;
}
template <typename _Tp,typename... Args>void input(_Tp &t,Args &...args){input(t);input(args...);}
const int N=1e6+10;
int a[N],b[N],c[N];
int n;
void solve(){
int m=1;
int l=0,k=0;
input(n);
fer(i,0,n-1)
{
input(a[i]);
if(a[i]%2!=0)
b[k++]=a[i];
else
c[l++]=a[i];
}
int i=0,j=0;
int s=l+k;
while(m<=s)
{
if(m%3!=0){
if(k>i)
{
cout<<b[i++]<<" ";
}
else
cout<<c[j++]<<" ";
}
else
{
if(l>j)
{
cout<<c[j++]<<" ";
}
else
cout<<b[i++]<<" ";
}
m++;
}
}
signed main()
{
solve();
}