B(相对分子质量),J(统计个数)

B:相对分子质量,
链接:https://ac.nowcoder.com/acm/contest/11163/B
来源:牛客网

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m;
string str;
map<string , ll > mp;
void slove(){
    ll ans = 0;
    int rear = 0;  
    ll st[5050] = {0};   //模仿stack 
    str = str+"#";       //防止下标越界处理
    for(int i=0;i<str.length();i++){
        if(str[i]==')'){
            //(Aa2Ab2)10   //这种情况
            ll sum=0;
            while(st[rear]!=-1)sum+=st[rear--]; rear--;
            ll num = 0;
            while(str[i+1]>='0'&&str[i+1]<='9') i++,num=num*10+str[i]-'0';
            if(!num) num=1;
            st[++rear] = sum*num;
        }else if(str[i]=='('){
            st[++rear] = -1;    //放个flag
        }else if(str[i]>='A'&&str[i]<='Z'){
            string s = "";
            s = s+str[i];
            if(str[i+1]>='a'&&str[i+1]<='z') i++,s+=str[i];
            ll num = 0;
             //Aa25  这种情况
            while(str[i+1]>='0'&&str[i+1]<='9') i++,num=num*10+str[i]-'0';
            if(!num) num = 1;
            st[++rear] = num*mp[s];
        }
    }
    while(rear) ans+=st[rear--];   //所有的求和
    cout<<ans<<endl;
}
int main(){
    cin>>m>>n;
    string s; ll x;
    while(m--){
        cin>>s>>x;mp[s]  = x;
    }
    while(n--){
        cin>>str; slove();
    }
    return 0;
}

J:统计个数
链接:https://ac.nowcoder.com/acm/contest/11163/J
来源:牛客网

给出一张N个点M条边的图,假设图中有三个节点分别为a,b,c,若点a和点b之间有边并且b和c之间有边的话,我们就称(a,b,c)为一条线,同时视(c,b,a)和(a,b,c)为同一条线,而对于其他的组合则认为是和(a,b,c)不同的线。

如果(a,b,c)是一条线并且点a和点c之间也有边的话,我们称(a,b,c)构成一个三角,同理我们视由这三个点组成的三角为同一个三角,即(a, b, c)、(a, c, b)、(b, a, c)、(b, c, a)、(c, a, b)、(c, b, a)只能被算一次
请分别统计给定的图中,三角和线的数量

思路:200个点,可以跑一个Floyd,求得所有的p与q

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i, a, n) for (ll i = a; i <= n; i++)
#define bug(x) cout << #x << "===" << x << endl
#define Please return
#define AC 0 
inline int read(){int x = 0, f = 1;char ch = getchar();
    while(ch < '0' || ch > '9'){if (ch == '-')f = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9'){x = (x<<1) + (x<<3) + (ch^48);ch = getchar();}return x * f;}

int t , n , m , v, u,p,q; 
int mp[250][250];
void dfs(int k){
    rep(i,1,n){          //以i为中心 
        if(mp[k][i]){   //如果k到i有一条边 
            rep(j,1,n){
                if(j!=k && mp[i][j]){   
                //然后i到j有一条边,说明有一条线 
                    q++;
                //然后k到j有一条边,说明有一个角 
                    if(mp[k][j]) p++; 
                } 
            }
        }
    }
}
void slove(){
    memset(mp,0,sizeof(mp));
    p = q = 0;
    n = read() ; m =read();
    rep(i,1,m){
        v = read(); u = read();
        mp[v][u] = mp[u][v] = 1;
    }
    for(int i=1;i<=n;i++) dfs(i);
    if(!p) q=1;
    //cout<<p<<" "<<q<<endl;
    int g = __gcd(p,q);
    cout<<p/g<<"/"<<q/g<<endl;
}
int main(){
    ios::sync_with_stdio(0);cin.tie(0); 
    t = read();
    while(t--){
        slove();
    }
    Please AC;
}