第九届河南省省赛题目部分题解

就会做这几题,一下午的成果。

信道安全

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述
Alpha 机构有自己的一套网络系统进行信息传送。情报员 A 位于节点 1,他准备将一份情报 发送给位于节点 n 的情报部门。可是由于最近国际纷争,战事不断,很多信道都有可能被遭到监 视或破坏。 经过测试分析,Alpha 情报系统获得了网络中每段信道安全可靠性的概率,情报员 A 决定选 择一条安全性最高,即概率最大的信道路径进行发送情报。 你能帮情报员 A 找到这条信道路径吗? 
输入
第一行: T 表示以下有 T 组测试数据 ( 1≤T ≤8 )
对每组测试数据:
第一行:n m 分别表示网络中的节点数和信道数 (1<=n<=10000,1<=m<=50000)
接下来有 m 行, 每行包含三个整数 i,j,p,表示节点 i 与节点 j 之间有一条信道,其信
道安全可靠性的概率为 p%。 ( 1<=i, j<=n 1<=p<=100)
输出
每组测试数据,输出占一行,一个实数 即情报传送到达节点 n 的最高概率,精确到小数点后
6 位。
样例输入
1
5 7
5 2 100
3 5 80
2 3 70
2 1 50
3 4 90
4 1 85
3 1 70
样例输出
61.200000

解题思路:

和求最短路差不多,只是稍有变形要去求最大的安全系数最大的一条路。节点个数比较多,临接矩阵已经HOLD不住了。用SPFA求,只存边就可以。

dis[i],存放源点1到i的最大安全系数。SPFA最开始dis[start]=1,因为自己到自己绝对安全。

#include<cstdio>
#include<iostream>
#include<queue>
#define INF -0x3f3f3f3f

using namespace std;

const int MAXN = 10002;
struct node        ///定义节点。
{
    int x;         ///代表u到x有一条边
    double value;  ///u到x这条边的权值,再此为安全系数
    int next;      ///指向下一条以u为顶点的边
};
node e[50004];     ///用来存储图中的边
int vis[MAXN],st[MAXN]; 
///vis是标记数组,dis[i]存放源点到i的最大安全系数,st应该说是指针
double dis[MAXN];
void spfa(int start) ///使用spfa算法求源点start到各个点的最短路径。
{
    queue<int>qu;    ///定义队列
    vis[start] = 1;
    dis[start] = 1;  ///start到start安全为1
    qu.push(start);  ///源点入队
    int u,point;
    while(!qu.empty())
    {
        u = qu.front();  ///取队首元素,以其为新的源点
        qu.pop();
        vis[u] = 0;
        point = st[u];  ///指向以u为顶点的第一条边
        while(point != -1)
        {
            ///这里更新条件是乘法。安全系数是相乘的并取大的
            if(dis[u]*e[point].value > dis[e[point].x]) 
            {
                dis[e[point].x] = dis[u]*e[point].value;
                if(vis[e[point].x] == 0)
                {
                    vis[e[point].x] = 1;
                    qu.push(e[point].x);
                }
            }
            point = e[point].next;
        }
    }
}
int main()
{
    int t,n,m,s,d,safe;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        for(int i = 1; i <= n; i++)
        {
            vis[i] = 0;
            dis[i] = INF;
            st[i] = -1;
        }
        int j = 1;
        for(int i = 1; i <= m; i++)
        {
            scanf("%d%d%d",&s,&d,&safe); 
            ///注意是无向图,所以下面存的边这样写。
            e[j].x = d;
            e[j].value = safe*0.01;
            e[j].next = st[s];
            st[s] = j;
            j++;
            e[j].x = s;
            e[j].value = safe*0.01;
            e[j].next = st[d];
            st[d] = j;
            j++;
        }
        spfa(1);
        printf("%lf\n",dis[n]*100);
    }
    return 0;
}


机器设备

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述

Alpha 公司设计出一种节能的机器设备。它的内部结构是由 N 个齿轮组成。整个机器设备有 一个驱动齿轮,当启动它时,它立即按 10,000 圈/小时转速顺时针转动,然后它又带动与它相切 的齿轮反方向,即逆时针转动。齿轮之间互相作用,每个齿轮都可能驱动着多个齿轮,最终带动 一个工作齿轮完成相应的任务。 在这套设备中,记录了每个齿轮的圆心坐标和齿轮半径。已知驱动齿轮位于(0,0),最终的 工作齿轮位于(Xt, Yt)。 Alpha 公司想知道传动序列中所有齿轮的转速。所谓传动序列,即能量由驱动齿轮传送,最 后到达工作齿轮的过程中用到的所有齿轮。能量传送过程是,在一个半径为 R,转速为 S 圈/每小 时的齿轮的带动下,与它相切的半径为 R’的齿轮的转速为-S*R/R’ 转/小时。负号的意思是, 表 示按反方向转动。

 

已知,机器设备中除了驱动齿轮以外,所有齿轮都可能被另外某个齿轮带动,并且不会出现 2 个不同的齿轮带动同一个齿轮的情况。 你的任务是计算整个传动序列中所有齿轮的能量之和。即所有齿轮转速的绝对值之和。 

输入
第一行: T 表示以下有 T 组测试数据(1≤T ≤8)
对每组测试数据:
第 1 行: N Xt Yt (2≤N ≤1100)
接下来有 N 行, Xi Yi Ri 表示 N 个齿轮的坐标和半径 i=1,2,….,N
( -5000 ≤Xi ,Yi ≤ 5000 3 ≤ Ri ≤ 1000 )
坐标以及半径是整数
输出
每组测试数据,输出占一行,即所有齿轮转速的绝对值之和 在double范围内,输出整数部分
样例输入
1
4 32 54
0 30 20
0 0 10
32 54 20
-40 30 20
样例输出
20000


解题思路:

从源点0,0这个齿轮开始,进行广搜,一旦搜到终点,输出答案即可。这个题目挺暴力的。每次都是以队首元素为新的起点,在n个齿轮中找到与该齿轮相切的齿轮并入队。

题目坑点:注意精度问题。

 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;

const int MAXN = 1102;
int N,XT,YT;        ///N齿轮个数,XT,YT目标位置
int vis[MAXN];      ///标记数组
struct ring     
{
    int x;      ///齿轮坐标
    int y;
    int R;      ///半径
}R[MAXN];       ///这个结构体数组仅是用来保存N个齿轮的信息
int sx,sy,sr;
struct node
{
    int x,y,r;      ///齿轮坐标半径
    double power;   ///当前齿轮的转速
    double sum;     ///到达当前齿轮经过所有齿轮的转速的绝对值和。
};
void bfs()          ///广搜一波
{
    node now,nex;    
    queue<node>qu;
    ///起点信息初始化
    now.x = sx;
    now.y = sy;
    now.r = sr;
    now.power = 10000.0;
    now.sum = 10000.0;
    qu.push(now);
    while(!qu.empty())
    {
        now = qu.front();
        qu.pop();
        if(now.x == XT && now.y == YT) ///注意目标齿轮是源点齿轮的情况
        {
            printf("10000\n");
            return;
        }
        ///在N个齿轮中找到与当前齿轮相切的并入队。
        for(int i = 1; i <= N; i++)
        {
            ///第i个齿轮没标记过
            if(vis[i]==0)  
            {
                /**注意这里判断两圆心距离,与半径和相同,则相切,希望大家都求距离的平方
                去判断,不要进行开方,那样可能精度缺失。直接求距离平方进行两整数比较很安全**/
                int left = (now.x-R[i].x)*(now.x-R[i].x)+(now.y-R[i].y)*(now.y-R[i].y);
                int right = (R[i].R + now.r)*(R[i].R + now.r);
                if(left == right) ///相切
                {
                    nex.x = R[i].x;
                    nex.y = R[i].y;
                    nex.r = R[i].R;
                    nex.power = (now.power*now.r)/(nex.r*1.0);
                    nex.sum = now.sum + nex.power;
                    if(nex.x == XT && nex.y == YT) ///如果是目标齿轮,则输出答案
                    {
                        /**sum+0.005是试出来的,原来为了四舍五入,加了0.5提交一直wa,
                        后来就想可能加的太大了,就式了式0.005,然后过了**/
                        printf("%d\n",(int)(nex.sum+0.005)); 
                        return;
                    }
                    vis[i] = 1;
                    qu.push(nex);
                }
            }
        }
    }
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&N,&XT,&YT);
        for(int i = 1; i <= N; i++)
        {
            vis[i] = 0;
            scanf("%d%d%d",&R[i].x,&R[i].y,&R[i].R);
            ///源点处的齿轮是在中间给出的,先判断保存下来,并将vis[i]置为1.因为起点一定入队
            if(R[i].x == 0 && R[i].y == 0)   
            {
                vis[i] = 1;
                sx = R[i].x;
                sy = R[i].y;
                sr = R[i].R;
            }
        }
        bfs();
    }
    return 0;
}
        


Decimal integer conversion

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述
XiaoMing likes mathematics, and he is just learning how to convert numbers between different bases , but he keeps making errors since he is only 6 years old. Whenever XiaoMing converts a number to a new base and writes down the result, he always writes one of the digits wrong. For example , if he converts the number 14 into binary (i.e., base 2), the correct result should be "1110", but he might instead write down "0110" or "1111". XiaoMing never accidentally adds or deletes digits, so he might write down a number with a leading digit of " 0" if this is the digit she gets wrong. Given XiaoMing 's output when converting a number N into base 2 and base 3, please determine the correct original value of N (in base 10). (N<=10^10) You can assume N is at most 1 billion, and that there is a unique solution for N. 
输入
The first line of the input contains one integers T, which is the nember of test cases (1<=T<=8)
Each test case specifies:
* Line 1: The base-2 representation of N , with one digit written incorrectly.
* Line 2: The base-3 representation of N , with one digit written incorrectly.
输出
For each test case generate a single line containing a single integer , the correct value of N
样例输入
1
1010
212
样例输出
14

英文题目:

题目意思是:给出一个字符串是2进制,一个字符串是3进制,给出的两个字符串中都有一位是错误的。如果没有错误,这两个字符串转化成十进制应该是相等的。

现在就让求这个十进制数是几。

解题思路:暴力题,直接对第一个2进制字符串进行暴力枚举,并计算每次枚举后的十进制值。对3进制字符串也进行暴力枚举,并计算每次枚举后的十进制值。然后对2进制的

枚举结果与3进制的枚举结果进行比较,两个数相等即为答案。


 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;

///该函数将一个b进制的字符串化成十进制
long long int base(string a,int b) 
{
    long long int num = 0;
    for(int i = 0; i < a.length(); i++)
    {
        num = num*b + (a[i]-'0');
    }
    return num;
}
int main()
{
    long long int a[10000];
    long long int b[10000];
    int j,t,k;
    string a2;
    string a3;
    int T;
    cin >> T;
    while(T--)
    {
        cin >> a2 >>a3;
        for(int i=0;i<a2.length();i++) ///每次修改一位
        {
            if(a2[i] == '1')    ///如果该位是1,改为0
                a2[i]='0';
            else                ///走到else,说明该位为0,修改为1
                a2[i]='1';
            a[i] = base(a2,2);  ///求十进制数
            if(a2[i] == '1')    ///恢复
                a2[i]='0';
            else
                a2[i]='1';
        }
        j = 0;
        for(int i=0;i<a3.length();i++)
        {
            if(a3[i] == '1')
            {
                a3[i]='0';
                b[j++]=base(a3,3);
                a3[i]='2';
                b[j++]=base(a3,3);
                a3[i] = '1';
            }
            else if(a3[i] == '0')
            {
                a3[i] = '1';
                b[j++] = base(a3,3);
                a3[i] = '2';
                b[j++] = base(a3,3);
                a3[i] = '0';
            }
            else
            {
                a3[i] = '0';
                b[j++] = base(a3,3);
                a3[i] = '1';
                b[j++] = base(a3,3);
                a3[i] = '2';
            }
        }
        int flag = 1;
        ///这里进行两两比较,数相等输出即可
        for(k = 0; k < a2.length(); k++)
        {
            for(t = 0; t < j; t++)
            {
                if(a[k] == b[t])
                {
                    printf("%d\n",a[k]);
                    break;
                }
            }
        }
    }
    return 0;
}
        

Prototypes analyze

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述

ALpha Ceiling Manufacturers (ACM) is analyzing the properties of its new series of Incredibly Collapse-Proof Ceilings (ICPCs).  An ICPC consists of n layers of material, each with a different value of collapse resistance (measured as a positive integer). The analysis ACM wants to run will take the collapse-resistance values of the layers, store them in a binary search tree, and check whether the shape of this tree in any way correlates with the quality of the whole construction. Because, well, why should it not?  To be precise, ACM takes the collapse-resistance values for the layers, ordered from the top layer to the bottom layer,  and inserts them one-by-one into a tree. The rules for inserting a value v are:

• If the tree is empty, make v the root of the tree.

• If the tree is not empty, compare v with the root of the tree.

• If v is smaller, insert v into the left subtree of the root,

• otherwise insert v into the right subtree.

 

ACM has a set of ceiling prototypes it wants to analyze by trying to collapse them. It wants to take each group of ceiling prototypes that have trees of the same shape and analyze them together. For example , assume ACM is considering five ceiling prototypes with three layers each, as described by Sample Input 1 and shown in Figure C.1. Notice that the first prototype’s top layer has collapseresistance value 2, the middle layer has value 7, and the bottom layer has value 1. The second prototype has layers with collapse-resistance values of 3, 1, and 4 – and yet these two prototypes induce the same tree shape, so ACM will analyze them together. Given a set of prototypes, your task is to determine how many different tree shapes they induce.

 

输入
The first line of the input contains one integers T, which is the nember of test cases (1<=T<=8).
Each test case specifies :
● Line 1: two integers n (1 ≤ n ≤ 50), which is the number of ceiling prototypes to analyze,
and k (1 ≤ k ≤ 20), which is the number of layers in each of the prototypes.
● The next n lines describe the ceiling prototypes. Each of these lines contains k distinct
integers ( between 1 and 1e6, inclusive ) , which are the collapse-resistance values of the
layers in a ceiling prototype, ordered from top to bottom.
输出
For each test case generate a single line containing a single integer that is the number of different tree
shapes.
样例输入
15 32 7 11 5 93 1 42 6 59 7 3
样例输出
4

英文题:

题目意思很简单,就是给出n棵数的元素,每棵树有k个节点。然后对于每棵树构建一颗二叉排序树,然后判断这n棵树有多少种树形。

解题思路:

下午AC的第一道题目,我的数据结构教材上有判断两棵树相似的递归代码,也有构建二叉排序树的代码,所以看到这个题目感觉很简单,直接模板一套就过了。

首先要对每一棵树按照题目中给出的规则构造二叉排序树,构造完之后,开始暴力,对任意两棵树判断是否相似,如果相似的话,将他们合并与同一个集合。

所以这个题目我的解题方法是:构造二叉排序树+判断两棵树是否相似+并查集。


 
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;

const int MAXN = 55;
struct node
{
    int data;
    struct node *lchild;
    struct node *rchild;
};
typedef struct Set
{
    int rrank;
    int parent;
}UFSTree;
/**并查集算法。这里的代码都来自李春葆的书,它的并查集代码很麻烦,但是它有一个值域
rrank和树高是相同的,可以保证分离集合树的高度比较均衡。这样查找的时候平均查找次数就
会变少。毕竟是我接触的第一个并查集算法,自己比较熟悉也愿意用。可以直接用以一维数组实现。**/
void MAKE_SET(UFSTree t[],int n)
{
    int i;
    for(i = 1; i <= n; i++)
    {
        t[i].rrank = 0;
        t[i].parent = i;
    }
}
int FIND_SET(UFSTree t[],int x)
{
    if(x!=t[x].parent)
        return FIND_SET(t,t[x].parent);
    else
        return x;
}
void UNION(UFSTree t[],int x,int y)
{
    x = FIND_SET(t,x);
    y = FIND_SET(t,y);
    if(t[x].rrank > t[y].rrank)
        t[y].parent = x;
    else
    {
        t[x].parent = y;
        if(t[x].rrank == t[y].rrank)
            t[y].rrank++;
    }
} 
///头节点,数组,head[i]为第i棵二叉排序树的头节点
struct node *head[MAXN]; 
///将元素插入二叉排序树
int InsertNode(struct node *&p,int key)
{
    if(p == NULL)  ///如果当前二叉排序树为空,先建立根节点
    {
        p = (struct node*)malloc(sizeof(struct node));
        p->data = key;
        p->lchild = p->rchild = NULL;
        return 1;
    }
    else if(key < p->data) ///如果小于当前节点,递归插入左子树
        return InsertNode(p->lchild,key);
    else
        return InsertNode(p->rchild,key); ///大于等于的情况,递归插入右子树
};
///判断两棵树树形是否相似
bool IsLike(struct node *b1,struct node *b2)
{
    bool like1,like2;
    if(b1 == NULL && b2 == NULL) ///两棵树都是空,也是相似
        return true;
    else if(b1 == NULL || b2 == NULL) ///如果一颗树空,一颗树不空,树形不一样
        return false;
    else
    {
        like1 = IsLike(b1->lchild,b2->lchild); ///判断两棵树的左子树是否相似
        like2 = IsLike(b1->rchild,b2->rchild); ///判断两棵树的右子树是否相似
        return (like1 && like2);  ///左子树与右子树都相似,树形才是完全一样的。
    }
}
int main()
{
    int T,n,m,num;
    while(~scanf("%d",&T))
    {
        while(T--)
        {
            scanf("%d%d",&n,&m);
            for(int i = 1; i <= n; i++)
            {
                head[i] = NULL; ///第i棵树初始为空
                for(int j = 1; j <= m; j++)
                {
                    scanf("%d",&num);
                    InsertNode(head[i],num); ///将第i棵树的元素插入这颗树。
                }
            }
            UFSTree t[MAXN];
            MAKE_SET(t,n);
            ///暴力枚举,组合任意两棵树
            for(int i = 1; i <= n; i++)
                for(int j = 1; j <= n; j++)
                {
                    if(IsLike(head[i],head[j])) ///如果树形一样
                    {
                        UNION(t,i,j);  ///直接并查集进行集合合并
                    }
                }
            int ans = 0;
            for(int i = 1; i <= n; i++)
                if(t[i].parent == i)  ///统计有几颗分离集合树即是答案
                    ans++;
            printf("%d\n",ans);
        }
    }
}
        
 

表达式求值

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 3
描述
假设表达式定义为: 1. 一个十进制的正整数 X 是一个表达式。 2. 如果 X 和 Y 是 表达式,则 X+Y, X*Y 也是表达式; *优先级高于+. 3. 如果 X 和 Y 是 表达式,则 函数 Smax(X,Y)也是表达式,其值为:先分别求出 X ,Y 值的各位数字之和,再从中选最大数。 4.如果 X 是 表达式,则 (X)也是表达式。 例如: 表达式 12*(2+3)+Smax(333,220+280) 的值为 69。 请你编程,对给定的表达式,输出其值。  
输入
【标准输入】 第一行: T 表示要计算的表达式个数 (1≤ T ≤ 10) 接下来有 T 行, 每行是一个字符串,表示待求的表达式,长度<=1000
输出
【标准输出】 对于每个表达式,输出一行,表示对应表达式的值。
样例输入
3
12+2*3
12*(2+3)
12*(2+3)+Smax(333,220+280)
样例输出
18
60
69


解题思路:普通的表达式求值只包含+,-,*,/,这个题目没有给出 -  和 /,但是定义了新的运算,Smax。注意Smax(a,b)不是求a,b的最大值,题目中说的是将算a数位分离的和,b数位分离的和,取两者中大的。我做的时候就看错了,一直以为Smax是要两个数中的最大值。虽然定义了新的运算Smax,也不要紧,就将Smax看作S运算,S就是Smax这种运算的运算符。解题采用的方法是中缀表达式转化为后缀表达式,然后用后缀表达式求解表达式的值。问题的关键就是要规定运算符的优先级别。

这里我叫栈中的运算符为左运算符,中缀中的运算符为右运算符。首先左右括号我不去费事去规定优先级了。因为如果遇到了左括号,一定要进栈,不管什么时候,我们都要

先计算括号内的内容。所以,如果遇到左括号直接进栈,左括号进栈后,栈中左括号优先级最低。定为0.如果遇到右括号,就让栈里左括号前的全部出栈。

当遇到Smax时,我们要先进行Smax运算,因此S运算的优先级高于乘法运算。同样在数学中乘法运算是高于加法运算的。

因此优先级:

+  <    *    <    Smax

然后还有逗号,如果遇到了逗号,举个例子

Smax(100+200,Smax(300,400))

这种情况下,遇到逗号,首先100+200必须要先运算,因此遇到逗号的话,+号必须要出栈,从这里看出逗号的优先级比加号底。

因此优先级又变为:

,   <    +     <    *    <    Smax

则上面的表达式的后缀为:(在处理中缀的时候,遇到字符S,处理完毕后,跳过后三个字符,S字符即代表Smax运算)

100#200#+300#400#,S,S

然后计算后缀表达式的值。

遍历后缀表达式的每个字符:

遇到数字,计算数字的值并入操作数栈。

遇到加号,弹出两个元素,进行加法运算再将运算结果入栈。

遇到乘号,弹出两个元素,进行乘法运算再将运算结果入栈。

遇到S字符,弹出两个元素,并分别数位分离求和,将两个中较大的和值压入栈中。

遇到逗号,不进行任何操作。跳过即可。


#include<iostream>
#include<stdio.h>
#include<string>
#include<stack>
#define max(a,b) a>b? a:b

using namespace std;

int level(char ch) ///规定运算符级别
{
    int flag;
    switch(ch)
    {
        case 'S': flag = 4; break;
        case '*': flag = 3; break;
        case '+': flag = 2; break;
        case ',': flag = 1; break;
        default:  flag = 0;
    }
    return flag;
}
bool IsOp(char ch)  ///判断是否运算符
{
    if(ch == '+'||ch == '*'|| ch == 'S'|| ch == ',')
        return true;
    else
        return false;
}
void trans(string In,string &Post)    ///中缀转后缀
{
    Post = "";  ///Post用来存放后缀,初始化为空
    stack<char>st;
    char ch = '#';
    st.push(ch);
    int i = 0,len = In.length();
    while(i < len)
    {
        if(In[i] == '(')  ///遇到左括号必然进栈,其进栈后优先级必最小
        {
            st.push(In[i]);
            i++;
        }
        else if(In[i] == ')') ///遇到右括号,左括号前的都出栈
        {
            while(st.top() != '(')
            {
                Post = Post + st.top();
                st.pop();
            }
            st.pop(); ///左括号出栈,一对括号处理完毕
            i++;
        }
        else if(IsOp(In[i])) ///是运算符
        {
            while(level(st.top()) >= level(In[i])) ///栈顶运算符比当前运算符的级别高或相等,都要出栈
            {
                Post = Post + st.top();
                st.pop();
            }
            st.push(In[i]);
            if(In[i]=='S') i += 4; ///Smax为S运算符,直接跳过max三个字符
            else i++;              ///正常情况下,遍历下一字符
        }
        else   ///是数字
        {
            while(In[i] >= '0' && In[i] <= '9')
            {
                Post = Post + In[i];
                i++;
            }
            Post += '#';  ///用来#来分割数字
        }
    }
    while(!st.empty())  ///最后将栈中剩余的运算符都弹出
    {
        if(st.top()!='#')  
        {
            Post = Post + st.top();
        }
        st.pop();
    }
}
int Calculate(string Post)  ///计算后缀表达式
{
    int len = Post.length();
    int i = 0;
    stack<int>st;           ///操作数栈
    while(i < len)
    {
        if(Post[i] >= '0' && Post[i] <= '9')  ///是数字
        {
            int num = 0;
            while(Post[i] >= '0' && Post[i] <= '9')
            {
                num = num*10 + (Post[i]-'0');
                i++;
            }///数字结束必然是因为遇到#符号
            st.push(num);
            i++;   ///跳过#符号
        }
        else if(Post[i]==',')  ///遇到逗号不做任何处理
        {
            i++;
        }
        else
        {
            int num1 = st.top(); st.pop();
            int num2 = st.top(); st.pop();
            switch(Post[i])
            {
            case '+':
                {
                    st.push(num1+num2);
                    i++;
                    break;
                }
            case '*':
                {
                    st.push(num1*num2);
                    i++;
                    break;
                }
            case 'S':
                {
                    int temp1 = 0,temp2 = 0;
                    while(num1)
                    {
                        temp1 = temp1 + num1%10;
                        num1 = num1/10;
                    }
                    while(num2)
                    {
                        temp2 = temp2 + num2%10;
                        num2 = num2/10;
                    }
                    st.push(max(temp1,temp2));
                    i++;
                    break;
                }
            }
        }
    }
    return st.top();
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        getchar();
        string In,Post;
        cin>>In;   ///输入中缀表达式。
        trans(In,Post);
        //cout<<Post<<endl;
        cout<<Calculate(Post)<<endl;
    }
    return 0;
}


去年大一水平低没资格去参加省赛。今年就要去了,还挺激动的。为自己加油。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值