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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

牛客多校10 - Tournament(找规律)

發布時間:2024/4/11 编程问答 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 牛客多校10 - Tournament(找规律) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

題目鏈接:點擊查看

題目大意:現在有 n 個隊伍參加比賽,任意兩個隊伍之間都要進行一次比賽,也就是共需要進行 n * ( n - 1 ) / 2 次比賽,對于每個隊伍來說,必須要在第一場比賽的時候到達賽場,在最后一場比賽結束后離開賽場,在賽場上呆的時間即為貢獻,現在求出一種比賽的安排順序,使得每個隊伍的貢獻之和最小

題目分析:可以自己手玩一下找找規律,這里以 n = 6 為例,畫個圖:

上圖中表示了 n * ( n - 1 ) / 2 場比賽按照升序排列后,也就是按照紅色箭頭的方向依次比賽,相信肯定有不少同學在看完樣例后以為這樣是最優的,于是莽了一發,結果得到的是答案錯誤吧?

我來一步一步優化一下整體序列,使得每次都變的最優吧,首先求一下當前情況下,每個隊伍需要在賽場上滯留的天數

接下來我們不難發現,如果嘗試將 ( 2 , 3 ) 這個點移到 ( 1 , 3 ) 之后,可以使得隊伍 1 的貢獻加一,隊伍 2 和隊伍 3 的貢獻不變,隊伍 4 , 5 , 6 的貢獻減一,顯然這樣是更優的,于是我們移動一下

在此基礎上,我們發現前移 ( 2 , 4 ) 也是可以讓貢獻減少,于是再次更新順序

到此為止,可以得到當 n = 6 的答案序列了,是不是沒有看出任何規律?好,那我們繼續將 ( 2 , 5 ) , ( 2 , 6 ) 和 ( 3 , 4 ) 分別移動到相應的位置,看看結果會發生什么樣的變化

?

到此為止,差不多就可以稍微總結一下結論或者規律了, 首先默認初始時比賽的順序為最初的升序排列,對于一比賽不妨設為 ( i , j ) 滿足?i < j ,如果將 ( i , j ) 前移(先不要管將其移動到什么位置),則對整體的貢獻就是,i 前面的隊伍,貢獻會 +1 ,j 后面的隊伍,貢獻會 -1,用公式表達的話,( i , j ) 前移的貢獻就是 sum += ( i - 1 ) - ( n - j ) ,也就是說,對于一場比賽我們可以分為三種情況:

  • ( i - 1 ) - ( n - j ) < 0:這場比賽放在前面最優
  • ( i - 1 ) - ( n - j ) == 0:這場比賽放在中間最優
  • ( i - 1 ) - ( n - j ) > 0:這場比賽放在后面最優
  • 推廣一下發現這個結論對所有的 ( i , j ) 都適用,剩下的就是在三個部分中,各自排序的問題了,在上面手動模擬后,看的出中間部分和后面部分按照升序排列就好了,而前半部分需要按照 j 的升序排列,當 j 相同時再按照 i 的升序排列

    證明的話我也不會,畢竟是比賽時找規律亂搞出來的,不過看完之后應該感覺還是比較有道理是吧?

    實現就比較簡單了

    代碼:
    ?

    #include<iostream> #include<cstdio> #include<string> #include<ctime> #include<cmath> #include<cstring> #include<algorithm> #include<stack> #include<climits> #include<queue> #include<map> #include<set> #include<sstream> #include<cassert> #include<bitset> #include<unordered_map> using namespace std;typedef long long LL;typedef unsigned long long ull;const int inf=0x3f3f3f3f;const int N=310;bool maze[N][N];void init(int n) {for(int i=1;i<=n;i++)for(int j=i+1;j<=n;j++)maze[i][j]=true; }int main() { #ifndef ONLINE_JUDGE // freopen("data.in.txt","r",stdin); // freopen("data.out.txt","w",stdout); #endif // ios::sync_with_stdio(false);int w;cin>>w;while(w--){int n;scanf("%d",&n);init(n);vector<pair<int,int>>ans;for(int i=1;i<=n;i++)for(int j=i+1;j<=n;j++){if(i-1<n-j){ans.emplace_back(i,j);maze[i][j]=false;}}sort(ans.begin(),ans.end(),[&](pair<int,int>a,pair<int,int>b){if(a.second!=b.second)return a.second<b.second;return a.first<b.first; });for(int i=1;i<=n;i++)for(int j=i+1;j<=n;j++)if(maze[i][j])ans.emplace_back(i,j);for(auto it:ans)printf("%d %d\n",it.first,it.second);}return 0; }

    ?

    總結

    以上是生活随笔為你收集整理的牛客多校10 - Tournament(找规律)的全部內容,希望文章能夠幫你解決所遇到的問題。

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