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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

百练200题总结

發(fā)布時間:2024/1/18 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 百练200题总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

百練200題總結

1. 有趣的跳躍 = 充分利用數組下標+再進行排序遍歷

題目描述

描述
一個長度為n(n>0)的序列中存在“有趣的跳躍”當前僅當相鄰元素的差的絕對值經過排序后正好是從1到(n-1)。例如,1 4 2 3存在“有趣的跳躍”,因為差的絕對值分別為3,2,1。當然,任何只包含單個元素的序列一定存在“有趣的跳躍”。你需要寫一個程序判定給定序列是否存在“有趣的跳躍”。

輸入
一行,第一個數是n(0 < n < 3000),為序列長度,接下來有n個整數,依次為序列中各元素,各元素的絕對值均不超過1,000,000,000。
輸出
一行,若該序列存在“有趣的跳躍”,輸出"Jolly",否則輸出"Not jolly"。

結題思路

思路1(暴力):

  • 計算原序列中第1個到第n-1個元素與其后面一個元素的差值的絕對值,依次存放在數組中。
  • 對數組進行排序,遍歷數組是不是從1到n-1序列。
  • 若遍歷時,數組元素不等于自增量,則輸出"Not jolly",并return 0;若遍歷完后沒有return 0,則輸出"Jolly"。
  • 思路2(充分利用數組下標):

  • 定義一個數組a,初始化為0。
  • 從輸入序列的第二個元素開始,直到最后一個元素,計算每一個元素與上一個元素的絕對值,記為index,將a[index]賦值為1
  • 對a數組排序,遍歷數組a,看數組是否全部等于1。若不是,則輸出"Not jolly",若是,則輸出"Jolly"。
  • 源代碼

    #include <iostream> #include <cmath> #include <algorithm> using namespace std; int main() {int n;if(cin >> n){long long a[n];long long b[n-1];for(int i = 0; i < n; i++){cin >> a[i];}for(int i = 0; i < n-1; i++){b[i] = abs(a[i+1] - a[i]);}sort(b, b+n-1);for(int i = 0; i < n-1; i++){if(b[i] != i+1){cout << "Not jolly" << endl;return 0;}}cout << "Jolly" << endl;}return 0; } #include <iostream> #include <cmath> using namespace std; int main() {int n;int last, current;int a[3001] = {0};cin >> n;cin >> last;for(int i = 1; i < n; i++){cin >> current;a[abs(current - last)]++;last = current;}for(int i = 1; i < n; i++){//a數組若越界,也屬于此類 if(a[i] != 1){cout << "Not jolly" << endl;return 0;} }cout << "Jolly" << endl;return 0; }

    我的看法

    此題可暴力求解,也可充分利用數組的下標,只有滿足相鄰元素的差值正好是從1到(n-1)時,才能正常地遍歷數組a,值越界或差不滿足從1到(n-1)時,都會輸出Not jolly。另外,方法1的復雜度為nlogn2,方法2的復雜度為n,方法2較快。

    下次遇到此類題我要注意的地方

    易中難
    1.記錄a[i]=1,充分利用數組下標,進行遍歷,看value值是否都滿足要求。

    充分利用數組的下標

    此類題模板代碼

    for(int i = 1; i < n; i++){cin >> current;a[abs(current - last)]++;last = current;}

    2. 瑪雅歷 = 兩個獨立循環(huán) + 字符串比對函數

    題目描述

    描述

    上周末,M.A. Ya教授對古老的瑪雅有了一個重大發(fā)現。從一個古老的節(jié)繩(瑪雅人用于記事的工具)中,教授發(fā)現瑪雅人使用了一個一年有365天的叫做Haab的歷法。這個Haab歷法擁有19個月,在開始的18個月,一個月有20天,月份的名字分別是pop, no, zip, zotz, tzec, xul, yoxkin, mol, chen, yax, zac, ceh, mac, kankin, muan, pax, koyab, cumhu。這些月份中的日期用0到19表示。Haab歷的最后一個月叫做uayet,它只有5天,用0到4表示。瑪雅人認為這個日期最少的月份是不吉利的,在這個月法庭不開庭,人們不從事交易,甚至沒有人打掃屋中的地板。

    因為宗教的原因,瑪雅人還使用了另一個歷法,在這個歷法中年被稱為Tzolkin(holly年),一年被分成13個不同的時期,每個時期有20天,每一天用一個數字和一個單詞相組合的形式來表示。使用的數字是1~13,使用的單詞共有20個,它們分別是:imix, ik, akbal, kan, chicchan, cimi, manik, lamat, muluk, ok, chuen, eb, ben, ix, mem, cib, caban, eznab, canac, ahau。注意:年中的每一天都有著明確唯一的描述,比如,在一年的開始,日期如下描述: 1 imix, 2 ik, 3 akbal, 4 kan, 5 chicchan, 6 cimi, 7 manik, 8 lamat, 9 muluk, 10 ok, 11 chuen, 12 eb, 13 ben, 1 ix, 2 mem, 3 cib, 4 caban, 5 eznab, 6 canac, 7 ahau, ,8 imix, 9 ik, 10 akbal ……也就是說數字和單詞各自獨立循環(huán)使用。

    Haab歷和Tzolkin歷中的年都用數字0,1,……表示,數字0表示世界的開始。所以第一天被表示成:
    Haab: 0. pop 0
    Tzolkin: 1 imix 0
    請幫助M.A. Ya教授寫一個程序可以把Haab歷轉化成Tzolkin歷。

    輸入

    Haab歷中的數據由如下的方式表示:
    日期. 月份 年數

    輸入中的第一行表示要轉化的Haab歷日期的數據量。下面的每一行表示一個日期,年數小于5000。

    輸出

    Tzolkin歷中的數據由如下的方式表示:
    天數字 天名稱 年數

    第一行表示輸出的日期數量。下面的每一行表示一個輸入數據中對應的Tzolkin歷中的日期。

    結題思路

    方法1:將Haab歷轉化為一年中的第多少天,然后再轉成Tzolkin歷。

  • 定義數組分別存放兩種歷法的月份、日期和Haab歷的天數。
  • 根據輸入數據的格式,將每行輸入按照"%d. %s %d"的格式分別存到日,月,年中。按照兩種日歷的規(guī)則,將日月年按照計算規(guī)則轉化成第多少天,再轉化成Tzolkin歷。(這里需要注意的是:Tzolkin歷的每一天用一個數字和一個單詞相組合的形式來表示,他們是各自獨立循環(huán)使用的,即:每一天都是day為單位做循環(huán),沒有月份的說法,其只是一個數字的代表。)
  • 源代碼

    #include <iostream> #include <cstring> using namespace std; const int NAMELENGTH = 10; int main() {int n;int index;char HaabYue[19][NAMELENGTH] = {"pop", "no", "zip", "zotz", "tzec", "xul", "yoxkin", "mol", "chen", "yax", "zac", "ceh", "mac", "kankin", "muan", "pax", "koyab", "cumhu"};char TzolkinYue[20][NAMELENGTH] = {"imix","ik","akbal","kan","chicchan","cimi","manik","lamat","muluk","ok","chuen","eb","ben","ix","mem","cib","caban","eznab","canac","ahau"}; cin >> n;cout << n << endl;for(int j = 0; j < n; j++){int days;int day, year;char month[NAMELENGTH];scanf("%d. %s %d", &day, month, &year);int i;for(i = 0; i < 19; i++){if(!strcmp(HaabYue[i], month)){break;}}days = year * 365 + 20 * i + day;cout << days % 13 + 1 << " " << TzolkinYue[days % 20] << " " << days / 260 << endl;} return 0; }

    意見

  • 字符串比對函數strcmp():若兩個字符串相等,則返回0。用于if()中時,用!才能表示進入。
  • Tzolkin歷相互不影響,獨立循環(huán),總共可以表示260天。
  • 下次遇到此類題我要注意的地方

    易中難
    1.字符串比對函數strcmp()。
  • 定義字符二維數組來解決字符串比對問題。
  • 特別注意細節(jié)之處,尤其是月份是否從0開始,需要遍歷多少次。
  • 不知道為什么,我的代碼不能AC,但是測試用幾個用例都是能用的。需要得到解答!
  • 此類題模板代碼

  • 充分利用數組下標和value。
  • for(int i = 1; i < n; i++){cin >> current;a[abs(current - last)]++;last = current;}

    3. 走迷宮 = DFS + 防止回走 + 防止越界

    題目描述

    描述
    一個迷宮由R行C列格子組成,有的格子里有障礙物,不能走;有的格子是空地,可以走。
    給定一個迷宮,求從左上角走到右下角最少需要走多少步(數據保證一定能走到)。只能在水平方向或垂直方向走,不能斜著走。
    輸入
    第一行是兩個整數,R和C,代表迷宮的長和寬。( 1<= R,C <= 40)
    接下來是R行,每行C個字符,代表整個迷宮。
    空地格子用’.‘表示,有障礙物的格子用’#‘表示。
    迷宮左上角和右下角都是’.’。
    輸出
    輸出從左上角走到右下角至少要經過多少步(即至少要經過多少個空地格子)。計算步數要包括起點和終點。
    樣例輸入

    5 5 ..### #.... #.#.# #.#.# #.#..

    樣例輸出
    9

    結題思路

    方法1:深度優(yōu)先搜索

  • 輸入迷宮的長和寬。
  • 定義一個二維字符數組a[R][C]表示迷宮。
  • 從a[0][0]出發(fā),調用深度優(yōu)先的函數,傳入橫縱坐標和步數。
  • 在DFS函數中,判斷此坐標為最右下角,若是,則與目前最少的步數比較,將兩者的較小值賦值給minStep,并返回;若不是,則繼續(xù)判斷該坐標是否越界或為’#’,若滿足則返回。
  • 設置此坐標為’#’(可避免往回走,同時可以一個visit數組來避免往回走),對其上下左右方向進行DFS,傳過去的步數是+1的。然后將此坐標恢復為’.’。
  • 直到到達最右下角。
  • 源代碼

    #include <iostream> #include <cstring> #include <cstdio> using namespace std; char a[40][40]; int r, c; int count = 0; int minStep = 10000; int visit[41][41]; void DFS(int i, int j, int step) {if(i == r-1 && j == c-1){minStep = min(minStep, step);return;}if( i < 0 || i > r-1 || j < 0 || j > c-1 || a[i][j] == '#'){return;}a[i][j] = '#';DFS(i-1, j, step+1);DFS(i+1, j, step+1);DFS(i, j-1, step+1);DFS(i, j+1, step+1);a[i][j] = '.'; } int main() {cin >> r >> c;for(int i = 0; i < r; i++){for(int j = 0; j < c; j++){cin >> a[i][j];}}DFS(0, 0, 1);cout << minStep << endl;return 0; }

    題型分析

  • 此題屬于DFS,BFS類題,也是屬于圖類題。
  • 以后要做一個搜索類題目的比較合集。
  • 此題也可以用廣度優(yōu)先搜索做,目前還沒有嘗試。
  • 下次遇到此類題我要注意的地方

    易中難
    1.DFS要注意不能返回走,可設置a[i][j] = ‘#’,同時也可以設置一個visit數組來避免往回走。2.strcmp用于比較字符數組或兩個"aa"和"bb"是否相等。3. ==用來判斷同類型變量是否相等。
  • strcmp只能比較兩個字符串是否相等,不能比較字符串和char類型(’'單引號表示char,雙引號表示字符串)。
  • == 只能用于判斷兩個同類型的變量是否相等。
  • 在處理搜索類型題目時,要注意增加是否越界的條件
  • 此類題模板代碼

  • DFS防止回走。
  • int visit[41][41];

    或者

    a[i][j] = '#';DFS(i-1, j, step+1);DFS(i+1, j, step+1);DFS(i, j-1, step+1);DFS(i, j+1, step+1);a[i][j] = '.';

    4. 最大子序列和 = 只要是正數就相加

    題目描述

    結題思路

    思路1:動態(tài)規(guī)劃的方法:求出每個位置的目前最大子序列和

  • 從a[0]開始,比較當前最大子序列的和與其加下一個數,賦值給ans[i],得到每一個位置的最大子序列和。
  • ans數組中最大的那個值即是結果。
  • 源代碼

    #include <iostream> #include <stdlib.h> #include <cmath> using namespace std;int main() {int n;cin >> n;int *array, *ans;int cur_sum, max_sum;array = (int*)calloc(n+1, sizeof(int));for(int i = 0; i < n; i++){cin >> array[i];}cur_sum = max_sum = array[0];for(int i = 1; i < n; i++){cur_sum = cur_sum + array[i] > cur_sum ? cur_sum + array[i] : cur_sum;max_sum = max_sum > cur_sum ? max_sum : cur_sum;}cout << max_sum << endl; return 0; }

    題型分析

    下次遇到此類題我要注意的地方

    易中難
    1.求出到每個位置為止最大子序列和。

    5. 最大上升子序列和 = 如果當前值大于j位置的數,并且他們組成的上升序列和更大。則更新i位置的最大值 + 兩層for循環(huán) + if條件判斷 + calloc(stdlib.h)

    題目描述

    描述

    一個數的序列bi,當b1 < b2 < … < bS的時候,我們稱這個序列是上升的。對于給定的一個序列(a1, a2, …,aN),我們可以得到一些上升的子序列(ai1, ai2, …, aiK),這里1 <= i1 < i2 < … < iK <= N。比如,對于序列(1, 7, 3, 5, 9, 4, 8),有它的一些上升子序列,如(1, 7), (3, 4, 8)等等。這些子序列中序列和最大為18,為子序列(1, 3, 5, 9)的和.

    你的任務,就是對于給定的序列,求出最大上升子序列和。注意,最長的上升子序列的和不一定是最大的,比如序列(100, 1, 2, 3)的最大上升子序列和為100,而最長上升子序列為(1, 2, 3)

    輸入

    輸入的第一行是序列的長度N (1 <= N <= 1000)。第二行給出序列中的N個整數,這些整數的取值范圍都在0到10000(可能重復)。

    輸出

    最大上升子序列和

    樣例輸入

    7
    1 7 3 5 9 4 8

    樣例輸出

    18

    結題思路

    思路1:動態(tài)規(guī)劃的方法:找出第i個數(a)結尾的最大上升子串和。

  • 需滿足三個條件:在i之前的&&數組a中小于a[i]&&ans的最大值
    (1)下標在i之前。for(int j = i-1; j >= 0; j–)
    (2)a[j] < a[i] (上升序列)
    (3)ans的最大值。
  • 此i之前的最大上升子串和加上a[i] (此題中a[i]是大于0的)。
  • 思路2:如果當前值大于j位置的數,并且他們組成的上升序列和更大。則更新i位置的最大值。

    源代碼

    #include <iostream> #include <stdlib.h> #include <cmath> using namespace std; int findMaxIncSum(int ans[], int i, int a[])//第i個數(a)結尾的最大子串和 {int max = 0;for(int j = i-1; j >= 0; j--)//下標在i之前的&&數組a中小于a[i]的ans的最大值 {if(a[i] <= a[j])// 數組a中小于a[i]{continue;}else {if(ans[j] > max){max = ans[j];}}}return max + a[i]; } int main() {int n;cin >> n;int *array, *ans;int max_sum;array = (int*)calloc(n+1, sizeof(int));ans = (int*)calloc(n+1, sizeof(int)); for(int i = 0; i < n; i++){cin >> array[i];} for(int i = 0; i < n; i++){ans[i] = findMaxIncSum(ans, i, array);}max_sum = ans[0];for(int i = 1; i < n; i++){max_sum = max_sum > ans[i] ? max_sum : ans[i];} cout << max_sum << endl;return 0; } #include<bits/stdc++.h> using namespace std; int main(){int N,num[1010];int max[1010]; //存當前位置的最大上升序列的和 cin>>N;memset(max, 0, sizeof(max));for(int i = 0; i < N; ++i) {cin>>num[i];max[i] = num[i]; //如果是非常大的數無法加入上升序列,可能其本身就是最優(yōu)值 }for(int i = 1; i < N; ++i){for(int j = 0; j < i; ++j){if(num[i]>num[j]&&num[i]+max[j]>max[i]){ //如果當前值大于j位置的數,并且他們組成的上升序列和更大。則更新i位置的最大值 max[i] = num[i]+max[j];}}}int re = 0;for(int t:max) re = re>t?re:t; //從所有的序列最大值中找到最優(yōu)解 cout<<re;return 0; }

    題型分析

  • 動態(tài)規(guī)劃題,需要找出到每個位置為止,a[j] < a[i] && 的最大上升子串之和。
  • 此題中,a[i]是大于0的,若沒有此限制條件,則在findMaxIncSum中首先要判斷a[i]是否大于0,若小于則可以直接用上一個位置的最大上升子串和。
  • 此類動態(tài)規(guī)劃題的關鍵是:找到"num[i]>num[j]&&num[i]+max[j]>max[i]"此條件,滿足此條件的則需要判斷。
  • 下次遇到此類題我要注意的地方

    易中難
    1.動態(tài)規(guī)劃題,要特別注意改變某個位置最大值的條件
  • 用calloc動態(tài)分配內存。
  • 用動態(tài)規(guī)劃算法求出每個時刻的最大值。
  • 此類題模板代碼

    6. Yogurt factory = 要不要在上次生產時,多生產一些 + 用一個flag記錄上一次生產的日期(并更新)

    題目描述

    描述

    The cows have purchased a yogurt factory that makes world-famous Yucky Yogurt. Over the next N (1 <= N <= 10,000) weeks, the price of milk and labor will fluctuate weekly such that it will cost the company C_i (1 <= C_i <= 5,000) cents to produce one unit of yogurt in week i. Yucky’s factory, being well-designed, can produce arbitrarily many units of yogurt each week.
    在接下來的N周,牛奶和勞力的價格會波動,公司在第i周生產每單位酸奶的存儲費為C_i美分。公司每周可以生產任意單位的酸奶。
    Yucky Yogurt owns a warehouse that can store unused yogurt at a constant fee of S (1 <= S <= 100) cents per unit of yogurt per week. Fortuitously, yogurt does not spoil. Yucky Yogurt’s warehouse is enormous, so it can hold arbitrarily many units of yogurt.
    繼續(xù)存儲每單位酸奶每周花費S美分存儲費,酸奶不會過期且能存無限量。
    Yucky wants to find a way to make weekly deliveries of Y_i (0 <= Y_i <= 10,000) units of yogurt to its clientele (Y_i is the delivery quantity in week i). Help Yucky minimize its costs over the entire N-week period. Yogurt produced in week i, as well as any yogurt already in storage, can be used to meet Yucky’s demand for that week.
    每周交付Y_i單位鮮奶,每周生產量i和存儲量均可用于出售

    輸入

    • Line 1: Two space-separated integers, N and S.
      N周 S美分
    • Lines 2…N+1: Line i+1 contains two space-separated integers: C_i and Y_i.
      i周的存儲費C_i美分 每周交付量Y_i

    輸出

    • Line 1: Line 1 contains a single integer: the minimum total cost to satisfy the yogurt schedule. Note that the total might be too large for a 32-bit integer.
      制定最好的生產計劃,當交付Y_i時,總花費最少

    樣例輸入

    4 5
    88 200
    89 400
    97 300
    91 500

    樣例輸出

    126900

    提示

    OUTPUT DETAILS:

    In week 1, produce 200 units of yogurt and deliver all of it. In week 2, produce 700 units: deliver 400 units while storing 300 units. In week 3, deliver the 300 units that were stored. In week 4, produce and deliver 500 units.

    結題思路

    思路1:

  • 第一周的牛奶自給自足。
  • 第二周的牛奶判斷上一次(上一次生產的周不一定為上周)的生產費用+上一次生產的周到此周所有單位牛奶所花的存儲費用是否大于此周的生產費用,若大于,則此周生產;若小于則上一次生產時多生產此周交付量的牛奶。
  • 以后的周數以此類推。
  • 輸出最后的sum。
  • 源代碼

    #include <iostream> #include <cmath> #include <stdlib.h> using namespace std; long long c[10005], y[10005]; int main() {int n, s;long long sum = 0;cin >> n >> s;for(int i = 0; i < n; i++){cin >> c[i] >> y[i];} sum = c[0] * y[0];int flag = 0;for(int i = 1; i < n; i++){if(c[i] >= c[flag] + (i-flag) * s){sum += (y[i] * c[flag] + (i-flag) * s * y[i]);}else {sum += y[i] * c[i];flag = i;}}cout << sum << endl;return 0; }

    題型分析

  • (此解法是用貪心算法做的,但感覺其不一定是最優(yōu)的。要用動態(tài)規(guī)劃做才是最優(yōu)的(設置兩個循環(huán),并判斷最優(yōu)條件)。)
  • flag的設置,標志為上一次生產的周數。
  • 貪心算法:判斷當選的選擇與之前最優(yōu)的選擇誰更優(yōu),就選用哪種方法。
  • 下次遇到此類題我要注意的地方

    易中難
    1.動態(tài)規(guī)劃貪心算法題,要特別注意改變某個位置最大值的條件(要不要在上次生產時,多生產一些)
  • 英文題目;寫完中文翻譯之后,再去看英文,仔細理解題意。翻譯熟能生巧(看到英文界面不要怕,第一次做此種類型時,把它從頭到尾翻譯一遍,就知道到底是什么水平了)。
  • 貪心算法要善于找到最優(yōu)的比較條件,如花費的錢最后(需追溯到數組的上幾位數)。
  • 此類題模板代碼

    7. 無線網絡 = 并查集問題 + 找父親函數 + 將已修復的電腦表帶連接到同一個父親上(還需要做并查集的題)

    題目描述

    Description

    An earthquake takes place in Southeast Asia. The ACM (Asia Cooperated Medical team) have set up a wireless network with the lap computers, but an unexpected aftershock attacked, all computers in the network were all broken. The computers are repaired one by one, and the network gradually began to work again. Because of the hardware restricts, each computer can only directly communicate with the computers that are not farther than d meters from it. But every computer can be regarded as the intermediary of the communication between two other computers, that is to say computer A and computer B can communicate if computer A and computer B can communicate directly or there is a computer C that can communicate with both A and B.

    In the process of repairing the network, workers can take two kinds of operations at every moment, repairing a computer, or testing if two computers can communicate. Your job is to answer all the testing operations.

    Input

    The first line contains two integers N and d (1 <= N <= 1001, 0 <= d <= 20000). Here N is the number of computers, which are numbered from 1 to N, and D is the maximum distance two computers can communicate directly. In the next N lines, each contains two integers xi, yi (0 <= xi, yi <= 10000), which is the coordinate of N computers. From the (N+1)-th line to the end of input, there are operations, which are carried out one by one. Each line contains an operation in one of following two formats:

  • “O p” (1 <= p <= N), which means repairing computer p.
  • “S p q” (1 <= p, q <= N), which means testing whether computer p and q can communicate.
  • The input will not exceed 300000 lines.

    Output

    For each Testing operation, print “SUCCESS” if the two computers can communicate, or “FAIL” if not.

    Sample Input

    4 1
    0 1
    0 2
    0 3
    0 4
    O 1
    O 2
    O 4
    S 1 4
    O 3
    S 1 4

    Sample Output

    FAIL
    SUCCESS

    結題思路

    思路1:并查集問題(設置flag和容器來解決)

  • 初始化每臺電腦的位置,每臺電腦未修復的flag等于其序列i。
  • 定義一個vector類型的容器,將每個電腦能連接的其他的電腦的序列i push_back進其容器。
  • 當輸入’O’時,將此電腦修復,并將其表帶相連到每一個已修復的電腦祖宗中(father[rooty] = rootx),即father[rooty]的坐標值指向rootx
  • 當輸入’S’時,判斷其最開始的祖宗是不是同一個,若是則輸出success,若不是則輸出fail。
  • 源代碼

    #include <cstdio> #include <iostream> #include <cstring> #include <algorithm> #include <cstring>#include <cmath> using namespace std ; #define maxn 1010 bool flag[maxn] ; int father[maxn] ; vector<int> vv[maxn] ; int n , d ; struct node {int x , y ; } post[maxn] ; double fun(int x){return x*x*1.0 ; }void init(){memset(vv , 0 , sizeof(vv)) ; for(int i=1 ; i<=n ; i++){father[i] = i ; //初始化 每臺電腦為一個集合flag[i] = false ;// 所有電腦 初始狀態(tài)為損壞 for(int j =1 ; j<=n ; j++){if(i==j){continue ; }//為 i 電腦 鏈接 所有 可連接距離內的電腦double dis = sqrt(fun(post[i].x-post[j].x)+fun(post[i].y-post[j].y)) ; if(dis<=d){vv[i].push_back(j) ; }}}for(int i = 0 ; i < n; i++){cout << "vv" << i << ":";for(int j = 0; j < vv[i].size(); j++){cout << vv[i][j];}cout << endl;} } //查詢 x 所在集合的代表元素的編號 //同時 理順集合內元素的關系(為剛合并的兩個集合找出統(tǒng)一的代表) int find(int x){if(x!=father[x])father[x] = find(father[x]) ; return father[x] ; }void Union_set(int x , int y){int rootx = find(x) ; int rooty = find(y) ; if(rootx != rooty){father[rooty] = rootx ; // 將 第二個集合的帶表元素 連接到第一個集合 } }int main(){while(~scanf("%d %d" , &n , &d)){for(int i=1 ; i<=n ; i++){scanf("%d%d" , &post[i].x , &post[i].y) ; }init() ; char str[3] ; int x , y ; while(~scanf(" %s" , str)){//scanf(" %s" , str) ; if(str[0] == 'O'){scanf("%d" , &x) ; flag[x] = true ; for(int j=0 ; j<vv[x].size() ; j++){int k = vv[x][j] ; if(flag[k]){//編號為 k 的電腦已經被修復 Union_set(x , k ) ; }}}else if(str[0] =='S'){scanf("%d %d" , &x , &y) ; int rootx = find(x) ; int rooty = find(y) ; if(rootx == rooty){printf("SUCCESS\n") ; } else {printf("FAIL\n") ; }}}}return 0 ; } #include <iostream> #include <cmath> #include <stdlib.h> #include <vector> #include <cstring> #include <algorithm> using namespace std; #define maxn 1005 bool flag[maxn]; int father[maxn]; struct node{int x, y; }pos[maxn]; vector<int> vv[maxn]; // 容器數組 int n, d; // $1. 全局變量的好處就是不用在函數中傳來傳去了。 void initSet() {memset(vv, 0, sizeof(vv));for(int i = 0; i < n ; i++){cin >> pos[i].x >> pos[i].y;}for(int i = 0; i < n; i++){flag[i] = 0; father[i] = i; // 每個點為自己的祖先 for(int j = 0; j < i; j++){if(i == j){continue;}if(pow((pos[i].x-pos[j].x), 2) + pow((pos[i].y-pos[j].y), 2) <= pow(d, 2)){vv[i].push_back(j);}}} }int getFather(int x) {if(x != father[x]){father[x] = getFather(father[x]);}return father[x]; }void becomeAFamily(int x, int y) {int rootx = getFather(x);int rooty = getFather(y);if(rootx != rooty){father[rooty] = rootx;} }int main() {cin >> n >> d;initSet();char str[3];int x, y;while(~scanf(" %s", str)){if(str[0] == 'O'){scanf("%d" , &x) ; flag[x] = 1;for(int j = 0; j < vv[x].size(); j++){int k = vv[x][j];if(flag[k]){becomeAFamily(x, k);}}}if(str[0] == 'S'){cin >> x >> y;int rootx = getFather(x);int rooty = getFather(y);if(rootx == rooty){cout << "SUCCESS" << endl;}else{cout << "FAIL" << endl;}}}return 0; }

    題型分析

  • 并查集問題,使用成為"成為家庭"和"找父親"的方法解決。
  • 下次遇到此類題我要注意的地方

    易中難
    1.熟悉"成為家庭"和"找父親"函數。
  • 測試它的樣本是怎么從出發(fā)到結束的。
  • 特別注意所有的電腦都壞了,需要一個一個來修復;并且,當一個電腦修復后,其肯定能和其他。
  • memset初始化數組、容器等。
  • 代碼1,是不是應該還要考慮當x和k的祖宗不能成為一家人時,就不需要進行集合的連接呢?這里還需要考慮一下。
  • 代碼2有一點問題,沒找出來。
  • 此類題模板代碼

  • 構造可達集合模板代碼
  • for(int i=1 ; i<=n ; i++){father[i] = i ; //初始化 每臺電腦為一個集合flag[i] = false ;// 所有電腦 初始狀態(tài)為損壞 for(int j =1 ; j<=n ; j++){if(i==j){continue ; }//為 i 電腦 鏈接 所有 可連接距離內的電腦double dis = sqrt(fun(post[i].x-post[j].x)+fun(post[i].y-post[j].y)) ; if(dis<=d){vv[i].push_back(j) ; }}}
  • 找父親和并查集的模板代碼
  • //查詢 x 所在集合的代表元素的編號 //同時 理順集合內元素的關系(為剛合并的兩個集合找出統(tǒng)一的代表) int find(int x){if(x!=father[x])father[x] = find(father[x]) ; return father[x] ; }void Union_set(int x , int y){int rootx = find(x) ; int rooty = find(y) ; if(rootx != rooty){father[rooty] = rootx ; // 將 第二個集合的帶表元素 連接到第一個集合 } }

    8. Arctic Network = 距離的問題劃為排序題 + 計算每個基站與前i-1個基站的距離存到動態(tài)數組中 + (int *)malloc(sizeof(int) * n)

    題目描述

    http://bailian.openjudge.cn/practice/2349/

    結題思路

    思路1:

  • 每輸入一個基站坐標時,計算其與前面i-1個基站的距離,存入distance數組中。
  • 給distance數組排序,輸入v-sitelliteC的值。
  • 源代碼

    #include <iostream> #include <cmath> #include <iomanip> #include <stdlib.h> #include <algorithm> using namespace std; int coordinate[501][2] = {0}; int main() {int n;int *a;int sitelliteC, outpostC;double *distance;int v = 0;cin >> n;for(int i = 0; i < n; i++){a = (int *)calloc(n, sizeof(int));//a = (int *)malloc(sizeof(int)*n);cin >> sitelliteC >> outpostC;distance = (double *)calloc(outpostC*(outpostC-1)/2, sizeof(double));for(int j = 0; j < outpostC; j++){cin >> coordinate[j][0] >> coordinate[j][1];for(int p = 0; p < j; p++){distance[v] = sqrt(pow(coordinate[j][0]-coordinate[p][0], 2) + pow(coordinate[j][1]-coordinate[p][1], 2));v++;}sort(distance, distance+v, greater<double>());} // for(int i = 0; i < v; i++) // { // cout << "distance[" << i << "]:" << distance[i] << endl; // } // cout << v << endl; // cout << sitelliteC << endl;cout << setiosflags(ios::fixed) << setprecision(2) << distance[v-sitelliteC] << endl;}return 0; }

    題型分析

  • c++格式輸出
  • #include <iomanip> cout << setiosflags(ios::fixed) << setprecision(2) <<

    下次遇到此類題我要注意的地方

    易中難
    1.setiosflags(ios::fixed) << setprecision(2)。2.sort()函數。

    此類題模板代碼

  • c++格式輸出
  • #include <iomanip> cout << setiosflags(ios::fixed) << setprecision(2) <<
  • sort函數模板
  • #include <algorithm> sort(a, a+n, greater<>())

    9. 數與字符串 = 從左到右對照每一個數排列,每一個數都盡量取最大的(9) + 整型與字符串的轉換(to_string()整型轉字符串 + itoa(num, a, 10)整型轉char [])

    題目描述

    http://bailian.openjudge.cn/xly2019/A/

    結題思路

    思路1:

  • 輸入一個整數。
  • 將整數轉化為字符串,記位數為len,并判斷此字符串的位數,若len為1,則直接輸出此字符串。若大于1,則進入下一步。
  • 判斷此字符串的最高位的情況,若最高位為9,則是直接輸出輸出此字符串;若最高位不為9,則輸出len-1位9。
  • 源代碼

    #include <iostream> #include <cmath> #include <stdlib.h> #include <cstring> #include <algorithm> using namespace std; int MAX = 10000; int main() {string a[MAX];string res[MAX];int num;cin >> num;int i = 0;while(num != 0){if(num < 10){res[i] = to_string(num);}else{a[i] = to_string(num);if(res[i][0] == '9'){res[i] = a[i];}else{int len = a[i].length();int tmp = pow(10, len-1)-1;res[i] = to_string(tmp);}cin >> num;i++;}}for(int j = 0; j < i; j++){cout << res[j] << endl;}return 0; }

    題型分析

  • 字符串和整型轉換題、夾雜著字典序。
  • 字典序:從左到右對照每一個數排列,每一個數都盡量取最大的(9)。
  • 下次遇到此類題我要注意的地方

  • 對于string類型
    使用to_string(int value)將整型轉為string類型。
  • 對于char a[]
    使用itoa(int value, char * a, radix)將整型轉換為char a[]。
  • memset()的頭文件是cstring。
    ||易|中|難|
    |-|-|-|-|
    |緊||1. 字符串的轉換。2. 字典序。||
    |般||||
    |必||||
  • 此類題模板代碼

  • 整型轉string類型
  • res[i] = to_string(num);
  • 整型轉char a[]型,char a[]轉string。
  • int num; cin >> num; char a[10]; // 整型轉char a[]型,itoa,a為char a[]。 itoa(num, a, 10); // char a[]轉string,直接賦值 string b = a; cout << b;

    題目描述

    結題思路

    源代碼

    題型分析

    下次遇到此類題我要注意的地方

    易中難

    此類題模板代碼

    題目描述

    結題思路

    源代碼

    題型分析

    下次遇到此類題我要注意的地方

    易中難

    此類題模板代碼

    題目描述

    結題思路

    易中難

    源代碼

    題型分析

    下次遇到此類題我要注意的地方

    易中難

    此類題模板代碼

    題目描述

    結題思路

    源代碼

    題型分析

    下次遇到此類題我要注意的地方

    易中難

    此類題模板代碼

    題目描述

    結題思路

    源代碼

    題型分析

    下次遇到此類題我要注意的地方

    易中難

    此類題模板代碼

    題目描述

    結題思路

    源代碼

    題型分析

    下次遇到此類題我要注意的地方

    易中難

    此類題模板代碼

    題目描述

    結題思路

    源代碼

    題型分析

    下次遇到此類題我要注意的地方

    易中難

    此類題模板代碼

    題目描述

    結題思路

    源代碼

    題型分析

    下次遇到此類題我要注意的地方

    易中難

    此類題模板代碼

    <–>

    總結

    以上是生活随笔為你收集整理的百练200题总结的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。