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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

字节--房间分配

發布時間:2024/4/11 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 字节--房间分配 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

字節–房間分配

文章目錄

  • 字節--房間分配
    • 一、問題描述
    • 二、分析
    • 三、代碼

一、問題描述

有n個房間,現在i號房間里的人需要被重新分配,分配的規則是這樣的:先讓i號房間里的人全都出來,接下來按照 i+1, i+2, i+3, ... 的順序依此往這些房間里放一個人,n號房間的的下一個房間是1號房間,直到所有的人都被重新分配。

現在告訴你分配完后每個房間的人數以及最后一個人被分配的房間號x,你需要求出分配前每個房間的人數。數據保證一定有解,若有多解輸出任意一個解。

  • 輸入描述:
第一行兩個整數n, x (2<=n<=10^5, 1<=x<=n),代表房間房間數量以及最后一個人被 分配的房間號;第二行n個整數 a_i(0<=a_i<=10^9) ,代表每個房間分配后的人數。
  • 輸出描述:
輸出n個整數,代表每個房間分配前的人數。輸入例子1: 3 1 6 5 1輸出例子1: 4 4 4

二、分析

  • 來解釋一下,題目里面的i是某一個房間i,我們不知道是那個具體的房間i,并不是所有房間都要重新分配,只是i房間重新分配.

初始情況:

4 4 4

現在第3房間的人重新分配

(為了與語言一致,即使得房間編號從0開始,代碼中會認為是2號房間

4 4 0

1 1 1

1

最終結果為

6 5 1

  • 題目本身不涉及什么算法,純模擬。
  • 第一種想法是,從最后一個分配房間逆推,每個房間減一個人,直到遇到某個房間人數減為0。
  • 這個過程所減的總人數就是i號房間的人數,其它房間也變為起始人數。按照這個想法編碼,case率80%,超時。
  • 第二種想法是找到分配房間i的位置,再根據i房間當中的人數來還愿所有房間的人數
  • 如下圖中所示:
  • 首先我們假設這個數組中人數最少的房間就是起始房間分配后的結果(就是問題當中的i房間)。因為每一次分配給其他所有房間1個人之后才給它自己分配1個人,所以最少人數的房間才有可能是i號房間。
  • 如果發現有多個相同的最小值,那么就以終止房間x遞減到第一個對應的最小值為準。

因為如果出現2個或者2個以上的最小值相等的情況,那么就說明i房間當中的人數無法分配一圈,一旦i房間中的人數可以分配一圈,那么i房間的人數增加1,其他所有房間都增加1,不可能出現相等的情況,所以如果出現多個相同的最小值的時候以終止房間x遞減到第一個對應的最小值為準

  • 上述對應圖中標紅部分,我們可以順著推,從起始房間i開始分配,最后i的值為min_val,那么也就是說每個房間都至少加了min_val個數(因為分配時是從下一個開始的,i房間的人數都分配到min_val個,那么其他房間肯定至少有min_val個)。
  • 最后終止于房間x也即是說從起始房間向右轉一圈到x又增加了1,即是圖中標紅的部分增加了min_val+1,藍色部分則是表明只增加了min_val,相當于最后一圈并沒有轉完,只轉到x位置就停止了。
  • 此時我們再看起始節點,根據計算的話應該是上述增加的和,合并起來其實就是=min_valn+d,因為每個都分配了min_val個,紅色部分長度為d,每個多加1,所以增加1d的數量即可。

三、代碼

#include <bits/stdc++.h> using namespace std; int main() { int n ; int x ; cin>>n>>x; //數組,存放每個房間分配完成后的人數long* person_now = new long[n];//保存數組中最少的人數,用來確定那個房間的人數被分配出去,即題目中的i房間 long min_value = INT_MAX; for(int i = 0; i < n; i++) { cin>>person_now[i]; min_value = min(min_value, person_now[i]); } //題目中的房間號是從1開始的,所以-1int index = x - 1; //用來保存沒有轉完一圈剩下的房間數,即x到i房間的距離,圖中的dint count = 0; //開始,(index + n) % n的原因是index是不斷減小的,因為在分配i房間人數時是以//i,i + 1,....,n,1,2,...i這種順序的,所以我們是反著來還原的,即//index,index - 1,....1,0,n,n - 1,....index,所以是為了防止越界訪問//!= min_value目的有兩個://1.因為我們是以index遞減的順序遍歷的,那么第一個和min_val值相等的房間//剛好就是題目中的i號房間,也就是把人數拿出來分配的房間,避免了相同的min_val//情況;//2.從index遞減到第一個等于min_val房間之間的所有房間一定是至少分配了//min_val + 1個人,也就是圖中的紅色部分,+ 1就是紅色部分比藍色部分//多走的半圈while(person_now[(index + n) % n] != min_value) { //還原紅色部分的原始房間person_now[(index + n) % n] -= min_value + 1; //遞減index下標index--; count++; } //還原第i號房間的原始人數,就是最少房間的人數person_now[(index + n) % n] = min_value * n + count;index--;//還原圖中的藍色部分的原始人數,就是只分配了min_val個人數,最后沒走完//一圈剩下的房間數while((index + n) % n != x - 1) {person_now[(index + n) % n] -= min_value;index--;}//打印結果for(int i = 0; i < n; i++) {cout<<person_now[i]<<" ";}return 0; }

總結

以上是生活随笔為你收集整理的字节--房间分配的全部內容,希望文章能夠幫你解決所遇到的問題。

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