省赛

54 篇文章 0 订阅
16 篇文章 0 订阅

表达式求值

时间限制: 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
来源
河南省第九届省赛

 
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<list>
#include<vector>
#include<stack>
#include<cmath>
using namespace std;
const int maxn=10010;
char str[1010];
char judge(char pre,char now){
    if(now=='+'){
        if(pre=='+'||pre=='*')return '>';
        return '<';
    }
    if(now=='*'){
        if(pre=='*')return '>';
        return '<';
    }
    if(now==','){
        if(pre=='(')return '<';
        else return '>';
    }
    if(now==')'){
        if(pre=='(')return '=';
        return '>';
    }
    if(now=='('){
        return '<';
    }
    if(now=='='){
        if(pre=='=')return '=';
        return '>';
    }
}
int Oper(int a,char oper,int b){
    if(oper=='+')return a+b;
    if(oper=='*')return a*b;
    if(oper==','){
        int num1=0,num2=0;
        while(a){
            num1+=a%10;
            a/=10;
        }
        while(b){
            num2+=b%10;
            b/=10;
        }
        return max(num1,num2);
    }
}
int main()
{
    int t,i,j,k;
    scanf("%d",&t);
    while(t--){
        scanf("%s",str);
        bool sign=false;
        int len=strlen(str),num=0;
        str[len]='=';len++;
        stack<int>s1;stack<char>s2;
        s2.push('=');
        for(i=0;i<len;++i){
            if(str[i]=='+'||str[i]=='*'||str[i]==','||str[i]=='('||str[i]==')'||str[i]=='='){
                if(sign){
                    s1.push(num);num=0;sign=false;
                }

                switch(judge(s2.top(),str[i])){
                    case '<':
                        s2.push(str[i]);
                        break;
                    case '=':
                        s2.pop();
                        break;
                    case '>':
                        int a = s1.top();s1.pop();
                        int b = s1.top();s1.pop();
                        int c=Oper(a,s2.top(),b);
                        s1.push(c);s2.pop(); i--;
                        break;
                }
            }
            else if(str[i]>='0'&&str[i]<='9'){
                num=num*10+(str[i]-'0');sign=true;
            }
        }
        printf("%d\n",s1.top());
    }
    return 0;
}
        

信道安全

时间限制: 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
来源
河南省第九届省赛

 
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<queue>
#include<list>
#include<cmath>
#include<vector>
#define eps 1e-6
using namespace std;
const int maxn = 100010;
struct Node{
    int next,from,to;
    double value;
}A[maxn];
int head[maxn<<1],node;
void init(){
    node=0;
    memset(head,-1,sizeof(head));
}
void add(int u,int v,double value){
    A[node].from=u;A[node].to=v;
    A[node].value=value;
    A[node].next=head[u];
    head[u]=node++;
}
int n,m;
bool vis[maxn];
double dist[maxn];
double SPFA(int s,int t){
    queue<int>Q;
    memset(vis,false,sizeof(vis));
    memset(dist,0,sizeof(dist));
    vis[1]=true;Q.push(1);dist[1]=1;
    while(!Q.empty()){
        int top = Q.front();Q.pop();vis[top]=false;
        for(int k = head[top];k != -1 ; k = A[k].next){
            if(dist[A[k].to]<dist[top]*A[k].value){
                dist[A[k].to]=dist[top]*A[k].value;
                if(!vis[A[k].to]){
                    vis[A[k].to]=true;
                    Q.push(A[k].to);
                }

            }
        }
    }
    return dist[n];
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&m);
        init();int a,b;
        double value;
        for(int i=0;i<m;++i){
            scanf("%d%d%lf",&a,&b,&value);
            add(a,b,value/100.0);add(b,a,value/100.0);
        }
        printf("%.6lf\n",SPFA(1,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
来源
河南省第九届省赛

 
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<list>
#include<queue>
#include<vector>
#include<cmath>
#include<list>
#include<stack>
using namespace std;
const int maxn=1010;
struct Node{
    int x,y,r;
}A[maxn];
int s,g,n;
bool vis[maxn],flag;
bool judge(int a,int b){
    return (A[a].x-A[b].x)*(A[a].x-A[b].x)+(A[a].y-A[b].y)*(A[a].y-A[b].y)==(A[a].r+A[b].r)*(A[a].r+A[b].r);
}
double ans;
void dfs(int k,double v,double res){
    if(flag)return ;
    if(k==g){
        ans=res;flag=true;
        return ;
    }
    for(int i=0;i<n;++i){
        if(vis[i])continue;
        if(judge(k,i))vis[i]=true,dfs(i,-v*1.0*A[k].r/(A[i].r*1.0),res+fabs(-v*1.0*A[k].r/(A[i].r*1.0)));
    }
}
int main()
{
    int t,i,j,k,xt,yt;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&n,&xt,&yt);
        for(i=0;i<n;++i){
            scanf("%d%d%d",&A[i].x,&A[i].y,&A[i].r);
            if(A[i].x==0&&A[i].y==0)s=i;
            if(A[i].x==xt&&A[i].y==yt)g=i;
        }
        memset(vis,false,sizeof(vis));
        vis[s]=true;flag=false;
        dfs(s,10000,10000);
        printf("%d\n",(int)ans);
    }
    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
来源
河南省第九届省赛

 
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<list>
#include<cmath>
#include<vector>
using namespace std;
const int maxn=10010;
long long Calcu(char *s,long long k){
    long long ans=0;
    for(int i=0;s[i];++i){
        ans=ans*k+(s[i]-'0');
    }
    return ans;
}
char s2[maxn],s3[maxn];
int main()
{
    int t,k;
    scanf("%d",&t);
    while(t--){
        bool sign=false;
        long long ans;
        scanf("%s%s",s2,s3);
        for(int i=0;s2[i]&&!sign;++i){
            for(int bit2=i?0:1&&!sign;bit2<=1;++bit2){
                if(bit2==s2[i]-'0')continue;
                char pre=s2[i];s2[i]=bit2+'0';
                long long temp2=Calcu(s2,2ll);
                for(int j=0;s3[j]&&!sign;++j){
                    for(int bit3=j?0:1&&!sign;bit3<=2;++bit3){
                        if(bit3==s3[j]-'0')continue;
                        char pre1=s3[j];s3[j]=bit3+'0';
                        long long temp3=Calcu(s3,3ll);
                        if(temp3==temp2){
                            ans=temp2;sign=true;break;
                        }s3[j]=pre1;
                    }
                }
                s2[i]=pre;
            }
        }
        printf("%lld\n",ans);
    }
    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 106
, 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.
样例输入
1
5 3
2 7 1
1 5 9
3 1 4
2 6 5
9 7 3
样例输出
4
来源
河南省第九届省赛

 
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<list>
#include<vector>
#include<list>
#include<cmath>
using namespace std;
bool vis[110];
int mar[110][110],n,k;
struct Node{
    int data;
    Node *lson;
    Node *rson;
};
void build(Node* tree, Node* next,int i,int x){
    if(next->data>mar[i][x]){
        if(next->lson==NULL){
            Node* p = new Node;
            p->data=mar[i][x];
            next->lson=p;
            p->lson=p->rson=NULL;
            if(x==k)return ;
            build(tree,tree,i,x+1);

        }
        else
            build(tree,next->lson,i,x);
    }
    else {

        if(next->rson==NULL){
            Node* p = new Node;
            p->lson=p->rson=NULL;
            p->data=mar[i][x];
            next->rson=p;
            if(x==k)return ;
            build(tree,tree,i,x+1);
        }
        else
            build(tree,next->rson,i,x);
    }
}
Node** arr = new Node*[110];
bool judge(Node *tree1,Node *tree2){
    if(tree1->lson==NULL&&tree2->lson==NULL&&tree1->rson==NULL&&tree2->rson==NULL)return true;
    if(tree1->lson==NULL&&tree2->lson!=NULL)return false;
    if(tree1->lson!=NULL&&tree2->lson==NULL)return false;
    if(tree1->rson!=NULL&&tree2->rson==NULL)return false;
    if(tree1->rson==NULL&&tree2->rson!=NULL)return false;
    if(tree1->rson!=NULL&&tree2->rson!=NULL&&tree1->lson!=NULL&&tree2->lson!=NULL)return judge(tree1->lson,tree2->lson)&&judge(tree1->rson,tree2->rson);
    if(tree1->lson!=NULL&&tree2->lson!=NULL)return judge(tree1->lson,tree2->lson);
    if(tree1->rson!=NULL&&tree2->rson!=NULL)return judge(tree1->rson,tree2->rson);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&n,&k);
        for(int i=1;i<=n;++i){
            for(int j=1;j<=k;++j){
                scanf("%d",&mar[i][j]);
            }
            Node* tree = new Node;
            tree->lson=tree->rson=NULL;
            tree->data=mar[i][1];
            build(tree,tree,i,2);
            arr[i]=tree;
        }
        int ans=0;
        memset(vis,false,sizeof(vis));
        for(int i=1;i<=n;++i){
            if(vis[i])continue;ans++;
            for(int j=i+1;j<=n;++j){
                if(judge(arr[i],arr[j])){vis[j]=true;}
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}
        


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值