国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

《算法競(jìng)賽·快沖300題》每日一題:“糖果配對(duì)”

這篇具有很好參考價(jià)值的文章主要介紹了《算法競(jìng)賽·快沖300題》每日一題:“糖果配對(duì)”。希望對(duì)大家有所幫助。如果存在錯(cuò)誤或未考慮完全的地方,請(qǐng)大家不吝賜教,您也可以點(diǎn)擊"舉報(bào)違法"按鈕提交疑問(wèn)。

算法競(jìng)賽·快沖300題》將于2024年出版,是《算法競(jìng)賽》的輔助練習(xí)冊(cè)。
所有題目放在自建的OJ New Online Judge。
用C/C++、Java、Python三種語(yǔ)言給出代碼,以中低檔題為主,適合入門、進(jìn)階。


糖果配對(duì)” ,鏈接: http://oj.ecustacm.cn/problem.php?id=1735

題目描述

【題目描述】 現(xiàn)在有N個(gè)小朋友,有M個(gè)不同的糖果。每個(gè)小朋友有自己最喜歡的糖果和第二喜歡的糖果。
?? 給定一些糖果,小朋友們會(huì)排隊(duì)來(lái)領(lǐng)糖果,對(duì)于每個(gè)小朋友而言,如果其最喜歡的糖果還在,將會(huì)選擇最喜歡的糖果,否則選擇第二喜歡的糖果。
?? 如果二者都不在,那么這個(gè)小朋友將會(huì)哇哇大哭。
?? 你可以任意排列對(duì)小朋友排隊(duì)的順序,但是要保證哭的小朋友數(shù)量最小。
?? 請(qǐng)求出最小的哭泣小朋友的數(shù)量。
【輸入格式】 輸入格式
?? 輸入第一行包含N和M。(N,M≤100000)
?? 接下來(lái)有N行,每i行包含兩個(gè)數(shù)字fi和si表示第i個(gè)小朋友最喜歡和第二喜歡的糖果編號(hào)。
【輸出格式】 輸出一個(gè)數(shù)字表示答案。
【輸入樣例】

8 10
2 1
3 4
2 3
6 5
7 8
6 7
7 5
5 8

【輸出樣例】

1

題解

?? 每個(gè)孩子有最喜歡的糖果和次喜歡的糖果,從二者中選擇一個(gè),相當(dāng)于一個(gè)孩子連接了兩個(gè)糖果。把孩子和糖果建模為一個(gè)圖,孩子是圖上的邊,糖果是圖上的點(diǎn)。要求每條邊和每個(gè)點(diǎn)進(jìn)行配對(duì),問(wèn)最多有多少個(gè)點(diǎn)和邊能夠匹配?
?? 把樣例畫(huà)成下面的圖,圖中的邊是孩子,點(diǎn)是孩子喜歡的糖果。例如邊{1-2}是第1個(gè)孩子喜歡的糖果1、2。根據(jù)樣例的數(shù)據(jù)畫(huà)出2個(gè)連通子圖,一個(gè)子圖是{1,2,3,4},它是一棵樹(shù);一個(gè)子圖是{5,6,7,8},它是一個(gè)有環(huán)圖。
《算法競(jìng)賽·快沖300題》每日一題:“糖果配對(duì)”,算法競(jìng)賽快沖300題,算法

?? 容易分析得出:如果連通子圖是一棵樹(shù),則匹配的數(shù)量就等于邊數(shù),或者等于點(diǎn)的數(shù)量減一;如果連通子圖是一個(gè)有環(huán)圖,匹配的數(shù)量就等于點(diǎn)數(shù)。例如上圖中,左邊子圖是有3條邊的樹(shù),能滿足3個(gè)小朋友;右邊子圖是有4個(gè)點(diǎn)的有環(huán)圖,能滿足4個(gè)小朋友。
?? 本題經(jīng)過(guò)轉(zhuǎn)換后是這樣一個(gè)圖的連通性問(wèn)題:(1)構(gòu)造圖;(2)查詢其中有多少連通子圖;(3)對(duì)每個(gè)子圖,區(qū)分它是樹(shù)還是有環(huán)圖,分別統(tǒng)計(jì)邊和點(diǎn)的數(shù)量。
?? 圖的連通性,編碼可以用BFS、DFS、并查集。下面用編碼比較簡(jiǎn)單的并查集求解。
?? 首先讀取點(diǎn)和邊,用并查集處理,屬于同一個(gè)子圖的點(diǎn),它們的集都相同,同時(shí)用ring標(biāo)注這個(gè)集是否是有環(huán)圖。
?? 如何用并查集處理有環(huán)圖?讀2個(gè)點(diǎn)u、v構(gòu)成的邊u-v時(shí),如果發(fā)現(xiàn)u、v已經(jīng)在以前讀取和處理過(guò),且屬于一個(gè)集,說(shuō)明邊u-v把原來(lái)的子圖變成了一個(gè)有環(huán)圖。
?? 讀取和處理完所有的點(diǎn)和邊后,上面圖示的的兩個(gè)子圖變成了下面的兩個(gè)并查集。并查集2中包含點(diǎn){1, 2, 3, 4},并查集6中包含點(diǎn){5, 6, 7, 8}。
《算法競(jìng)賽·快沖300題》每日一題:“糖果配對(duì)”,算法競(jìng)賽快沖300題,算法
?? 請(qǐng)注意兩個(gè)關(guān)鍵:
?? (1)并查集必須用路徑壓縮,這樣才能使得一個(gè)集中的每個(gè)點(diǎn)所屬的集相同,例如{1, 2, 3, 4}都屬于并查集2。
?? (2)需要標(biāo)記每個(gè)并查集是樹(shù)還是有環(huán)圖。下面的代碼用參數(shù)ring來(lái)標(biāo)記一個(gè)點(diǎn)是否在有環(huán)圖上。只要這個(gè)并查集中有一個(gè)點(diǎn)的ring標(biāo)記為true,這個(gè)并查集就是一個(gè)有環(huán)圖。
?? 最后就是搜索有多少并查集,并統(tǒng)計(jì)每個(gè)并查集內(nèi)部有多少個(gè)糖果匹配。只需用O(nlogn)的計(jì)算量即可完成這2個(gè)任務(wù):
?? (1)對(duì)所有并查集按集的大小排序,例如{1, 2, 3, 4}、{5, 6, 7, 8}這個(gè)兩個(gè)并查集的點(diǎn)對(duì)應(yīng)的集是{2, 2, 2, 2}、{6, 6, 6, 6},按集的大小排序后,同一個(gè)集的點(diǎn)都排在一起。排序的計(jì)算量為O(nlogn)。
?? (2)從小到大遍歷所有的集,如果集的大小一樣,它們就屬于一個(gè)集。統(tǒng)計(jì)這個(gè)集內(nèi)部的糖果匹配數(shù)量。計(jì)算量為O(n)。
【重點(diǎn)】 圖的連通性 。

C++代碼

??

#include<bits/stdc++.h>
using namespace std;
const int N = 1e5+10;
struct child {int s; bool ring;} c[N];         //s: 并查集;  ring:這個(gè)點(diǎn)是否在一個(gè)有環(huán)圖上
bool cmp(struct child a, struct child b){ return a.s < b.s;}    //按s排序
int find_set(int x){                           //并查集:查詢
    if(c[x].s!=x)   c[x].s=find_set(c[x].s);   //路徑壓縮
    return c[x].s;
}
int main(){
    int n,m;    cin>>n>>m;
    for(int i=1;i<=m;i++)  c[i].s = i,c[i], c[i].ring = false;       //并查集初始化
    for(int i=1;i<=n;i++) {
        int u,v;  cin>>u>>v;                 //讀取一條邊上的兩個(gè)點(diǎn)
        u = find_set(u);                     //查詢它們的集
        v = find_set(v);
        if(u==v){                //已經(jīng)是同一個(gè)集,說(shuō)明這個(gè)集是一個(gè)有環(huán)圖
            c[u].ring = true;    //標(biāo)注這個(gè)集是一個(gè)有環(huán)圖
            continue;            //已經(jīng)在一個(gè)集中了,不用合并
        }
        c[v].s = c[u].s;         //u、v還不在一個(gè)集中,進(jìn)行并查集合并
    }
    for(int i=1;i<=m;i++)
        find_set(i);                 //利用查詢進(jìn)行路徑壓縮,使同一個(gè)集的點(diǎn)的所屬的集相同
    sort(c+1,c+m+1,cmp);             //對(duì)集排序,讓同一個(gè)集的點(diǎn)排在一起
    int tot = 0;                     //統(tǒng)計(jì)能滿足多少小朋友
    for(int i=2;i<=m;i++) {          //遍歷有多少個(gè)集
        bool Ring = false;           //這個(gè)集是否為有環(huán)圖,初始化為非環(huán)圖
        int point = 1;               //統(tǒng)計(jì)這個(gè)集表示的連通子圖內(nèi)有多少個(gè)點(diǎn)
        while(c[i].s == c[i-1].s) {    //如果兩點(diǎn)的集s相同,說(shuō)明它們屬于同一個(gè)子圖
            if(c[i-1].ring || c[i].ring )  Ring = true;  //這個(gè)集是一個(gè)有環(huán)圖
            point++;                   //統(tǒng)計(jì)這個(gè)集合的點(diǎn)的數(shù)量            
i++;                       //遍歷這個(gè)集
        }
        if(Ring==false) point--;      //不是有環(huán)圖,是一棵樹(shù)
        tot += point;
    }
    cout<<n-tot;          //不能滿足的小朋友人數(shù)
    return 0;
}

Java代碼

import java.util.*;
public class Main {
    static class Child {
        int s;
        boolean ring;
        public Child(int s, boolean ring) {
            this.s = s;
            this.ring = ring;
        }
    }
    static Child[] c;
    static int n, m;
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        m = scanner.nextInt();
        int N = 100010;
        c = new Child[N + 1];
        for (int i = 1; i <= N; i++)   c[i] = new Child(i, false);
        for (int i = 1; i <= n; i++) {
            int u = scanner.nextInt();
            int v = scanner.nextInt();
            u = findSet(u);
            v = findSet(v);
            if (u == v) {
                c[u].ring = true;
                continue;
            }
            c[v].s = c[u].s;
        }
        for (int i = 1; i <= m; i++)       findSet(i);
        Arrays.sort(c, 1, m + 1, new Comparator<Child>() {
            public int compare(Child a, Child b) { return a.s - b.s; }
        });
        int tot = 0;
        for (int i = 2; i <= m; i++) {
            boolean ring = false;
            int point = 1;
            while (c[i].s == c[i - 1].s) {
                if (c[i - 1].ring || c[i].ring)   ring = true;
                point++;
                i++;
            }
            if (!ring)   point--;
            tot += point;
        }
        System.out.println(n - tot);
    }
    static int findSet(int x) {
        if (c[x].s != x)   c[x].s = findSet(c[x].s);
        return c[x].s;
    }
}

Python代碼

??文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-657736.html

import sys
sys.setrecursionlimit(1000000)
import functools
N = 100010
class Child:
    def __init__(self, s, ring):
        self.s = s
        self.ring = ring
def cmp(a, b):   return a.s - b.s
def find_set(x):
    if c[x].s != x:  c[x].s = find_set(c[x].s)
    return c[x].s
c = []
n, m = map(int, input().split())
for i in range(N):  c.append(Child(i, False))
for i in range(1,n+1):
    u, v = map(int, input().split())
    u = find_set(u)
    v = find_set(v)
    if u == v:
        c[u].ring = True
        continue
    c[v].s = c[u].s
for i in range(1, m + 1):  find_set(i)
c[1:] = sorted(c[1:], key=functools.cmp_to_key(cmp))
tot = 0
i = 2
while i <= m:
    Ring = False
    point = 1
    while c[i].s == c[i - 1].s:
        if c[i - 1].ring or c[i].ring:  Ring = True
        point += 1
        i += 1
    if not Ring:  point -= 1
    tot += point
    i += 1
print(n - tot)

到了這里,關(guān)于《算法競(jìng)賽·快沖300題》每日一題:“糖果配對(duì)”的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來(lái)自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場(chǎng)。本站僅提供信息存儲(chǔ)空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請(qǐng)注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請(qǐng)點(diǎn)擊違法舉報(bào)進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 《算法競(jìng)賽·快沖300題》每日一題:“湊二十四”

    《 算法競(jìng)賽·快沖300題 》將于2024年出版,是《算法競(jìng)賽》的輔助練習(xí)冊(cè)。 所有題目放在自建的OJ New Online Judge。 用C/C++、Java、Python三種語(yǔ)言給出代碼,以中低檔題為主,適合入門、進(jìn)階。 “ 湊二十四 ” ,鏈接: http://oj.ecustacm.cn/problem.php?id=1793 【題目描述】 給你n個(gè)數(shù)字,

    2024年02月11日
    瀏覽(18)
  • 《算法競(jìng)賽·快沖300題》每日一題:“松鼠與栗子”

    《 算法競(jìng)賽·快沖300題 》將于2024年出版,是《算法競(jìng)賽》的輔助練習(xí)冊(cè)。 所有題目放在自建的OJ New Online Judge。 用C/C++、Java、Python三種語(yǔ)言給出代碼,以中低檔題為主,適合入門、進(jìn)階。 “ 松鼠與栗子 ” ,鏈接: http://oj.ecustacm.cn/problem.php?id=1852 【題目描述】 現(xiàn)在有m棵栗

    2024年02月11日
    瀏覽(23)
  • 羅勇軍 → 《算法競(jìng)賽·快沖300題》每日一題:“排列變換” ← 貪心算法

    【題目來(lái)源】 http://oj.ecustacm.cn/problem.php?id=1812 http://oj.ecustacm.cn/viewnews.php?id=1023 【題目描述】 給定一個(gè)長(zhǎng)度為 n 的排列 a,需要將這個(gè)排列變成 b。 每次可以選擇一個(gè)數(shù)字往左移若干個(gè)位置。 請(qǐng)求出 最小需要移動(dòng)的元素個(gè)數(shù) 。 【輸入格式】 第一行為正整數(shù) n,1≤n≤100000。

    2024年02月12日
    瀏覽(24)
  • 羅勇軍 →《算法競(jìng)賽·快沖300題》每日一題:“乘積” ← 動(dòng)態(tài)規(guī)劃

    【題目來(lái)源】 http://oj.ecustacm.cn/problem.php?id=1781 http://oj.ecustacm.cn/viewnews.php?id=1023 【題目描述】 給你一個(gè)長(zhǎng)度為 n 的序列,序列中的元素只包括 1 和 -1。 請(qǐng)問(wèn)有多少個(gè)連續(xù)的子序列乘積為正數(shù)。 【輸入格式】 輸入第一行為正整數(shù) n。(n不超過(guò)10^6) 第二行包含 n 個(gè)整數(shù)。 【輸

    2024年02月11日
    瀏覽(19)
  • 羅勇軍 →《算法競(jìng)賽·快沖300題》每日一題:“游泳” ← DFS+剪枝

    【題目來(lái)源】 http://oj.ecustacm.cn/problem.php?id=1753 http://oj.ecustacm.cn/viewnews.php?id=1023 【題目描述】 游泳池可以等分為n行n列的小區(qū)域,每個(gè)區(qū)域的溫度不同。 小明現(xiàn)在在要從游泳池的左上角(1, 1)游到右下角(n, n),小明只能向上下左右四個(gè)方向游,不能游出泳池。 而小明對(duì)溫度十分

    2024年02月10日
    瀏覽(19)
  • 【LeetCode每日一題】——575.分糖果

    【LeetCode每日一題】——575.分糖果

    哈希表 簡(jiǎn)單 575.分糖果 Alice 有 n 枚糖,其中第 i 枚糖的類型為 candyType[i] 。Alice 注意到她的體重正在增長(zhǎng),所以前去拜訪了一位醫(yī)生。 醫(yī)生建議 Alice 要少攝入糖分,只吃掉她所有糖的 n / 2 即可(n 是一個(gè)偶數(shù))。Alice 非常喜歡這些糖,她想要在遵循醫(yī)生建議的情況下,盡可

    2024年02月13日
    瀏覽(29)
  • 算法|每日一題|H 指數(shù)|二分

    原題地址: 力扣每日一題:H 指數(shù) 給你一個(gè)整數(shù)數(shù)組 citations ,其中 citations[i] 表示研究者的第 i 篇論文被引用的次數(shù)。計(jì)算并返回該研究者的 h 指數(shù)。 根據(jù)維基百科上 h 指數(shù)的定義:h 代表“高引用次數(shù)” ,一名科研人員的 h 指數(shù) 是指他(她)至少發(fā)表了 h 篇論文,并且每

    2024年02月08日
    瀏覽(20)
  • 每日一題之常見(jiàn)的排序算法

    排序是最常用的算法,常見(jiàn)的排序算法有冒泡排序、選擇排序、插入排序、快速排序、希爾排序和歸并排序。除此之外,還有桶排序、堆排序、基數(shù)排序和計(jì)數(shù)排序。 1、冒泡排序 冒泡排序就是把小的元素往前放或大的元素往后放,比較的是相鄰的兩個(gè)元素。 時(shí)間復(fù)雜度:

    2024年02月13日
    瀏覽(20)
  • 算法每日一題:贖金信 | 字符和整數(shù)

    hello,大家好,我是星恒 今天給大家?guī)?lái)的題目是一道簡(jiǎn)單題目,主要幫大家復(fù)習(xí)一下字符串和字符的相關(guān)操作 給你兩個(gè)字符串:ransomNote 和 magazine ,判斷 ransomNote 能不能由 magazine 里面的字符構(gòu)成。 如果可以,返回 true ;否則返回 false 。 magazine 中的每個(gè)字符只能在 ransom

    2024年01月21日
    瀏覽(21)
  • 【迎戰(zhàn)藍(lán)橋】 算法·每日一題(詳解+多解)-- day5

    【迎戰(zhàn)藍(lán)橋】 算法·每日一題(詳解+多解)-- day5

    ??目錄?? ??1. 數(shù)組中出現(xiàn)次數(shù)超過(guò)一半的數(shù)字 ??2.?二進(jìn)制中1的個(gè)數(shù) ??3.?替換空格 【大家好,我是 愛(ài)干飯的猿 ,如果喜歡這篇文章, 點(diǎn)個(gè)贊 ??, 關(guān)注一下吧, 后續(xù)會(huì)一直分享題目與算法思路 】 描述 給一個(gè)長(zhǎng)度為 n 的數(shù)組,數(shù)組中有一個(gè)數(shù)字出現(xiàn)的次數(shù)超過(guò)數(shù)組長(zhǎng)

    2023年04月08日
    瀏覽(21)

覺(jué)得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請(qǐng)作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包