日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

PAT甲级1114 Family Property:[C++题解]结构体、并查集、测试点3、4、5有问题的进来!!

發(fā)布時(shí)間:2025/4/5 c/c++ 19 豆豆
生活随笔 收集整理的這篇文章主要介紹了 PAT甲级1114 Family Property:[C++题解]结构体、并查集、测试点3、4、5有问题的进来!! 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

文章目錄

    • 題目分析
    • 題目鏈接

題目分析



來源:acwing

分析:

  • 先建邊。讀入每家的信息,在本人和父母(如果有的話),本人與子女(如果有的話)之間分別建邊。邊用結(jié)構(gòu)體來存,邊記錄兩個(gè)端點(diǎn)。
  • 遍歷每條邊合并集合,分成一個(gè)一個(gè)家庭。這里的“遍歷每條邊”,指的是遍歷兩條邊的端點(diǎn)(戶主,或父母,或子女),利用find()函數(shù)合并,這里把id大的掛到id小的上面,這樣,根結(jié)點(diǎn)就是答案所求的戶主id。
  • 將每個(gè)家庭存入vector,排序輸出即可。為此,需要一個(gè)Family結(jié)構(gòu)體,里面存戶主id,家庭人數(shù)c,家庭房子數(shù)量hc,家庭房子面積ha,并重載小于號(hào)進(jìn)行排序。
  • 需要注意的點(diǎn):

  • 用int表示id,不用string。起初想用string來表示id,發(fā)現(xiàn)較為麻煩。原因有二,一是用string之后,用并查集之后還需要一步從string到int 的映射,教麻煩。二是題目明確每個(gè)id都是4位數(shù),并且各不相同,這是變相地給我們降級(jí)難度,提示我們使用int。
  • 家庭戶主的id是編號(hào)最小的。由于我們是用并查集做的,這就提示我們只維護(hù)一個(gè)最小的id即可,其他id在統(tǒng)計(jì)到各個(gè)家庭之后沒有什么用。在并查集中,合并的時(shí)候把較大的root接到較小的root上,這樣得到的root就是最小的root。
  • 前導(dǎo)0的輸出,萬能C語言!!!由于用int來存的id,如果像0004這樣?jì)饍旱?#xff0c;存的只是4,這就考驗(yàn)我們的格式化輸出能力。使用printf("%04d",a);含義是以4位寬度輸出數(shù)a,不足4位的在前面補(bǔ)0!
  • 補(bǔ)充:printf("%4d",id)表示輸出寬度為4,且右對(duì)齊,不足的在前面補(bǔ)空格。當(dāng)變量的實(shí)際寬度大于4時(shí),輸出變量的所有數(shù)字.

    ac代碼

    #include<bits/stdc++.h> using namespace std; const int N = 10010; //邊的數(shù)量 int n; int p[N]; //并查集父親數(shù)組 int c[N];//c[i]表示i這家人的人數(shù) count int hc[N];//房子數(shù)量 house count int ha[N]; //房子面積 house area bool st[N];// 戶主 和父母,子女分別建邊 struct Edge{int a, b; }e[N];// 一家人放在一個(gè)結(jié)構(gòu)體中,排序使用 struct Family{int id ,c ,hc, ha;bool operator<(const Family & t)const{// ha /c , t.ha/t.cif( ha * t.c != c * t.ha) return ha * t.c > c* t.ha;return id < t.id;} };//并查集找根 int find(int x){if(p[x]!= x) p[x] = find(p[x]);return p[x]; }int main(){cin >>n;int m =0; //表示邊數(shù)//第一部分: 讀入所有輸入,并建邊for(int i = 0; i < n; i++){int id , father ,mother, k;cin >> id >> father >> mother >>k;//標(biāo)記id出現(xiàn)過st[id] = true;if(father != -1) e[m++] = {id,father};if(mother != -1) e[m++] = {id,mother};for(int j = 0 ;j< k; j++){int son;cin >> son;e[m++] ={id,son};}cin >> hc[id] >> ha[id]; //房子數(shù)量,房子面積}//第二部分:得到每個(gè)家庭,并且戶主編號(hào)最小//并查集初始化for(int i = 0; i<= N; i++) p[i] = i,c[i] =1 ;//i這家人只有1個(gè)人//遍歷每條邊:合并集合:得到每個(gè)家庭。for(int i = 0 ; i<m ;i++){int a = e[i].a, b = e[i].b;st[a] = st[b] = true; //標(biāo)記每個(gè)點(diǎn)出現(xiàn)過//一個(gè)集合的根結(jié)點(diǎn)int pa = find(a),pb = find(b);//合并集合,讓根結(jié)點(diǎn)大的集合掛到 根結(jié)點(diǎn)小的集合上!!//這樣根結(jié)點(diǎn)就是編號(hào)最小的那個(gè)!!!//題目要求:ID 是家庭成員中編號(hào)最小的成員編號(hào)if(pa != pb){if(pb > pa) swap(pa,pb); //讓pb成為較小的// 那么pb那個(gè)集合的值都要更新:加上pa集合的值//人數(shù) , 房子數(shù)量,房子面積c[pb] += c[pa],hc[pb]+= hc[pa],ha[pb] += ha[pa];//pa集合掛到編號(hào)更小pb集合p[pa] = pb; }}// 第三部分:每個(gè)家庭的信息存起來,并輸出vector<Family> familys;//遍歷所有的點(diǎn),如果之前出現(xiàn)過st[i] == true 并且是集合的根結(jié)點(diǎn)p[i] == i//代表i就是一家之主,將該家庭統(tǒng)計(jì)到vector中for(int i =0 ;i < N; i++){if(st[i] && p[i] == i)familys.push_back({i,c[i],hc[i],ha[i]});}//排序輸出sort(familys.begin(),familys.end());cout<< familys.size()<<endl;for( auto f :familys){printf("%04d %d %.3lf %.3lf\n",f.id, f.c,(double)f.hc/f.c,(double)f.ha/f.c);} }

    注意:測試點(diǎn)3、4、5包括0000這個(gè)人。第一遍忽略了這個(gè)人,導(dǎo)致三個(gè)測試點(diǎn)錯(cuò)誤。

    題目鏈接

    PAT甲級(jí)1114 Family Property
    https://www.acwing.com/problem/content/1606/

    總結(jié)

    以上是生活随笔為你收集整理的PAT甲级1114 Family Property:[C++题解]结构体、并查集、测试点3、4、5有问题的进来!!的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。