ハング電気再審査筆記試験2018-2019

私は18年の第三タイトルが聞かせ
、あなたはより多くの本の見ることができ、本当に最短経路と最小スパニングツリーを知らない
https://blog.csdn.net/spaceyqy/article/details/39024675

スイカスイカおじさん王昨年たくさんのお金。まともな収入を参照してください、今年彼は再びn個のスイカを開きました。
それは再生できないことがあります。スムーズな水に彼のn個のスイカを鎮火する、彼は地元のウェル中で選択することもスイカのそれぞれに対して、補修パイプラインはまた、メロンはよくこれを打つこと(他のメロンに由来することができる与えるために、まあ、彼はまた、水を介して他のガルディア)のリードから水を描きました。
もちろん、掘削およびパイプラインの修理のコストの違い。ウェルズは私が取るi番目の要素のwiスイカで知られており、最初のiの間、j個のスイカは、パイプラインパイ、jの要素を修復するのにかかります。
質問は今ある:アンクル王はすべてガルディアを作るために多くのお金を費やす必要以上(掘削井戸やパイプラインや修理の費用)で、水で鎮火していますか?
グアルディアがより、アンクル王()ガーディアウェルれる選択することができないため、どのようなスイカとの間のパイプラインを修復します。
ヘルプアンクル王が決定、最小コストの値をプログラミングしてください。

(1 <= N <= 300,1 <=のWi <= 100000; PI、I = 0,1 <= PI、J = PJ、I <= 100000)

入力

行1、正の整数n、代表スイカの数。
次のn行を順次整数W1 ... WN(それぞれのスイカ掘削費用)指定されました。
* Nの行列が続くnは整数であり、行列のi番目の行は、j番目の列の数PI、J(二スイカ間のパイプを確立するコスト)を表します。各行は、スペースで区切られた2つの数字の間があります。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
//瓜农王大爷去年种西瓜赚了不少钱。看到收入不错,今年他又重新开辟了n个西瓜地。 
//为了能给他的n个西瓜地顺利的浇上水,对于每个西瓜地他可以选择在本地打井,也可以修管道从另一个瓜地(这个瓜地可能打了井;也可能没打井,他的水也是从其他瓜地引来的)将水引过来。 
//当然打井和修管道的费用有差别。已知在第i个西瓜地打井需要耗费wi元,在第i、j个西瓜地之间修管道需要耗费pi,j元。 
//现在的问题是:王大爷要想使所有瓜地都被浇上水,至少需要花费多少钱(打井与修管道的费用和)? 
//由于瓜地较多,王大爷无法选择在哪些(个)瓜地打井,哪些西瓜地之间修管道。 
//请你编程帮王大爷做出决策,求出最小费用。

//这道题和我之前写过的类似,就是求最短路径,可以将打井的钱,当做是从原点到该水管的距离,这样就增加了一些距离
//可以创建一个数组来存储第一位是起点,第二位是终点,值是对应距离
//用到并查集


    int a[100];//用来存对应点的祖宗
    int zuzong(int x){
        //找到某个点的祖宗
        if(a[x]==x)
            return x;
        else
            return zuzong(a[x]);
    }
    bool check(int x,int y){
        //判断两点是否同一个祖宗,也就是在不在同一个集合
        return zuzong(x)==zuzong(y);
    }
    void merge_1(int x,int y){
        //合并两个点到同一个祖宗,前提是他们不是同一个祖宗
        a[zuzong(x)]=zuzong(y);
    }
    int dis[100][100];
    int i,j;
    int n;//西瓜地的数量
 struct Y{
     int s,e,dis;//对应起点,终点,和对应距离

}Gua[100];
bool cmp(Y a,Y b){
    return a.dis<b.dis;//距离从小到大排序
}
int main(){
    scanf("%d",&n);
    int temp[100][100];//中间数组
    for(i=1;i<=n;i++){
            Gua[i].s=0;
            Gua[i].e=i;
            scanf("%d",&Gua[i].dis);
    }
    int m=n+1;//因为前面n个点已经记录了好了距离,所以需要从第n+1个点开始
    for(i=1;i<=n;i++)
        for(j=1;j<=n;j++){
        scanf("%d",&temp[i][j]);
        if(i<j){
            Gua[m].s=i;
            Gua[m].e=j;
          Gua[m].dis=temp[i][j];//修管道的费用,只输出单方向的,让无向图变成有向的
          m++;
        }
        }
    //对数组进行花费从小到大排序
    sort(Gua+1,Gua+m+1,cmp);//n是西瓜地数量,c是边数,默认从小到大

    //再将每个点,默认祖宗初始设置为自己
    for(i=0;i<=n;i++)
        a[i]=i;

    //开始合并
    int sum=0;
    for(i=1;i<=m;i++)//一共m条边
        if(!check(Gua[i].s,Gua[i].e)){//没有合并,那就合并,并且记录对应花费
            sum+=Gua[i].dis;
            merge_1(Gua[i].s,Gua[i].e);
        }

        printf("%d",sum);
}

最初の質問

問題の説明

人々のグループは、映画館に行きます。しかし、映画は非常に奇妙な要件ました:大人の座席数はわずか18歳以下の子供が唯一の番号は座席番号さえある割り当てることができ、奇数番号を割り当てることができます。
入力

ムービーにN個の個別の入力がある(1 <= N <1000) 、次のN個の個々の入力座席番号、各スペース区切り用座席番号
出力

アダルト動画とすべての人々の大人のシェアの数、未成年者とすべての人々のマイナーシェアの数の割合は、2つの小数点以下の桁数の計算比、各出力を確認するために、出力の割合スペースで区切られた
サンプル入力

8 13 12 10 8 3 24 21 19
サンプル出力

4 0.50 4 0.50

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
//第一题
//Problem Description
//有一群人去电影院看电影。但电影院有个很奇怪的规定:成人只能分到数字奇数座位号,未满18岁的儿童只能分到数字为偶数的座位号。
//Input
//输入共有n个人去看电影(1<=n<1000),接下来输入n个人的座位号,每个座位号用空格隔开
//Output
//依次输出此次看电影成人的人数以及成人在所有人中所占的比例、未成年人的人数以及未成年人在所有人中所占的比例,计算出的比例保留两位小数,每个输出用空格隔开
//Sample Input
//8 13 12 10 8 3 24 21 19
//Sample Output
//4 0.50 4 0.50

int main(){
    int i,n;//输入的人数
    int sum1=0;
    int sum2=0;
    int a[100];
    scanf("%d",&n);
    for(i=0;i<n;i++){
        scanf("%d",&a[i]);
        if((a[i]%2)==0)
            sum2++;
        else
            sum1++;
    }
    printf("%d %.2f %d %.2f",sum1,(1.0*sum1)/n,sum2,(1.0*sum2)/n);
}

問題の説明

図の中で示されるように、今鉛直木材の複数に追加される大型コンテナ、各標識された(I、YI)の木材SITトップは、ある
ここに画像を挿入説明
入力

n個の入力ボードの合計を加えた(1 <= N <1000) 、によりN次のnボードの高さに加え、デジタル入力表される各スペースの高さによって分離
出力

水の量を保持できる容器の最大数(容器の傾きを許容しない)の出力
サンプル入力

8 1 8 6 4 5 3 7 2
サンプル出力

35

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
//第二题,给n模板,输入n个值代表模板的高度,求最大容积
//我感觉就直接暴力,两次for循环,i从0-n-1 然后J 从i+1 到n-1 直接求最大值

int main(){
    int i,j,n;
    scanf("%d",&n);
    int a[100];
    for(i=0;i<n;i++)
        scanf("%d",&a[i]);
    int v,mmax=0;
    for(i=0;i<n;i++)
    for(j=i+1;j<n;j++){
        v=(j-i)*min(a[i],a[j]);
        if(v>mmax)
            mmax=v;
    }
    printf("%d",mmax);
}

問題の説明

人々のグループは、今、それらの間の友情をあなたに教えます。AとBが友達である場合、Bの友人はCで、その後、AとCも友人です。友人関係は、AとBは友達で、AとBも友達であること、双方向です。次にA、B、Cと同じ「友人の輪」で
入力

まず入力N、M表し、n型パーソナル、M関係(1 <= N <2000) 、続いてm行の各行の関係(人を表す各桁)を表す
出力を

で番号「友人の輪」との間の現在の入出力関係場合に
サンプルインプット
。8. 7
。1 2
2 4
4 1
5 7
4 3
6 2
7 8
サンプル出力
2

#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
using namespace std;
//第四题有点像是连通图, 求连通图的个数。那就是用dfs或者bfs,或者是用并查集,然后用一个coun++
struct Y{
    int s,e;
}fri[100];
int a[100];
int zuzong(int x){
    if(x==a[x])
        return x;
    else
        return zuzong(a[x]);
}
bool  check(int x,int y){
    return zuzong(x)==zuzong(y);
}
void merge_1(int x,int y){
    a[zuzong(x)]=zuzong(y);
}
int main(){
    int n,m;//n个人,m种关系
    int i,c=1;//初始值为1,假设都连通
    scanf("%d%d",&n,&m);
    for(i=0;i<m;i++){
        scanf("%d%d",&fri[i].s,&fri[i].e);
    }
    //先赋初始值
    for(i=1;i<=n;i++)
        a[i]=i;
    for(i=0;i<m;i++){
        if(!check(fri[i].s,fri[i].e)){//就是靠并查集来记录,有哪些是不一样的
            merge_1(fri[i].s,fri[i].e);
        }
    }
   //这个时候已经全都分好类了,然后就开始筛选吧,
   //我想到一个办法就是对数组进行排序,然后找到不一样的值
   //创建一个数组来存祖宗
   int temp[100];
   for(i=1;i<=n;i++)
   temp[i]=zuzong(i);
   //for(i=1;i<=n;i++)
    //printf("%d ",temp[i]);
   sort(temp+1,temp+1+n);
   int flag=temp[1];
   for(i=2;i<=n;i++){
    if(temp[i]!=flag){
        flag=temp[i];
        c++;
    }
   }


    printf("%d",c);

}
公開された72元の記事 ウォンの賞賛5 ビュー2802

おすすめ

転載: blog.csdn.net/qq_41115379/article/details/104983179