【2021-01-21】PAT(上級レベル)練習

1001 A + Bフォーマット(20ポイント)

  簡単なシミュレーションの質問。整数型を加算および減算して、結果を処理するだけです。

多項式の場合は1002A + B(25分)

  多項式を追加し、同じ係数を追加するだけです。要点に注意してください、係数は負であるかもしれません、判断条件の使用に注意してください。

1003緊急(25分)

  この問題は、最短経路問題を解決します。最短経路に基づいて、解決する最短経路の数と、最短経路にガードの数が最も多い最短経路が追加されます。
  1つ目は、ダイクストラのアルゴリズムで解決できる単一ソースの最短経路問題です。ただし、最短パスを更新する場合は、最短パスの数とガードの最大数を同時に更新し、等しいかそれ以上の2つのケースに対処する必要があります。

#include<bits/stdc++.h>
#define close ios::sync_with_stdio(false)
using namespace std;
const int maxn=3e5;
const int INF=0x3f3f3f3f;
struct Edge{
    
    
    int from,to,w;
    Edge(int a,int b,int c){
    
    from=a;to=b;w=c;}
};
vector<Edge> e[maxn];
int rescue_team[510];
struct s_node{
    
    
    int id,n_dis;
    s_node(int b,int c){
    
    id=b;n_dis=c;}
    bool operator <(const s_node &a)const{
    
    
        return n_dis>a.n_dis;
    }
};
int n,m;
int path_num[510],tot_num[510];
void Dijkstra(int s,int f)
{
    
    
    int dis[510];bool done[510];
    for(int i=0;i<n;++i) {
    
    dis[i]=INF;done[i]=false;path_num[i]=0;tot_num[i]=0;}
    dis[s]=0;path_num[s]=1;tot_num[s]=rescue_team[s];
    priority_queue<s_node> Q;
    Q.push(s_node(s,dis[s]));
    while(!Q.empty())
    {
    
    
        s_node u=Q.top();Q.pop();
        if(done[u.id]) continue;
        done[u.id]=true;
        for(int i=0;i<e[u.id].size();++i)
        {
    
    
            Edge y=e[u.id][i];
            if(done[y.to]) continue;
            if(dis[y.to]>y.w+u.n_dis){
    
    
                dis[y.to]=y.w+u.n_dis;
                Q.push(s_node(y.to,dis[y.to]));
                path_num[y.to]=path_num[u.id];
                tot_num[y.to]=tot_num[u.id]+rescue_team[y.to];
            }
            else if(dis[y.to]==y.w+u.n_dis){
    
    
                path_num[y.to]+=path_num[u.id];
                tot_num[y.to]=max(tot_num[y.to],tot_num[u.id]+rescue_team[y.to]);
            }
        }
    }
    cout<<path_num[f]<<' '<<tot_num[f]<<endl;
}
int main()
{
    
    
    close;int C1,C2;cin>>n>>m>>C1>>C2;
    for(int i=0;i<n;++i) cin>>rescue_team[i];
    for(int i=0;i<m;++i)
    {
    
    
        int x,y,w;cin>>x>>y>>w;
        e[x].push_back(Edge(x,y,w));
        e[y].push_back(Edge(y,x,w));
    }
    Dijkstra(C1,C2);
}

1004葉を数える(30分)

  (この質問が30ポイントの価値がある理由はわかりません...)ツリーの深さに関する簡単な質問の場合、DFSはツリーを再度実行します。ノードにサブノードがない場合は、このサブノードを指定します。深さ+1、それ以外の場合は続行します。DFS。

1005スペルイットライト(20分)

  単純な文字列処理の問題は、全員の合計結果が0であるという特別な判断に注意してください。

1006サインインおよびサインアウト(25分)

  主に時間の比較を調べるための簡単なシミュレーションの質問。ここは同じ日なので、すべての時間を秒に変えるという形を直接使用します。つまり、3600 ∗時間+ 60 ∗分+秒3600 *時間+ 60 *分+秒です。3 6 0 0h o u r+6 0m i n u t e+s e c o n d、質問の意味に応じて繰り返されない整数になるように、直接並べ替えるだけです。

1007最大サブシーケンス合計(25分)

  非常に単純なDPの問題ですが、ピットがあり、21〜22ポイントでピットインする可能性があります。この質問は非常に一般的です:dp [i − 1]> 0 dp [i-1]> 0の場合d p [ i1 ]>>0(最大シーケンスが最短になるようにするため、前のサブシーケンスの合計は寄与なしで0になります)、dp [i] = dp [i − 1] + a [i] dp [i] = dp [i -1] + a [i]d p [ i ]=d p [ i1 ]+a [ i ];否则dp [i] = a [i] dp [i] = a [i]d p [ i ]=a [ i ]次に、最大値に達するサブシーケンスの左右のエンドポイントを出力する必要があり、状態を記録できます。
  しかし、この質問の落とし穴は、上記の判断方法に従って最大値が0の場合、2つの状況が発生する可能性があることです。1つはすべての数値が負であり、もう1つはすべての数値が負で0です。0が含まれている場合は、元のシーケンスの左右の端点を出力しないように注意してください。

おすすめ

転載: blog.csdn.net/CUMT_William_Liu/article/details/112863200