1. 程式人生 > >HDU 5363 Average(貪心+腦洞)

HDU 5363 Average(貪心+腦洞)

Average

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 3032    Accepted Submission(s): 735
Special Judge


Problem Description There are n soda sitting around a round table. soda are numbered from 1 to n and i-th soda is adjacent to (i+1)-th soda, 1-st soda is adjacent to n
-th soda.

Each soda has some candies in their hand. And they want to make the number of candies the same by doing some taking and giving operations. More specifically, every two adjacent sodax and y can do one of the following operations only once:
1. x-th soda gives y-th soda a candy if he has one;
2. y
-th soda gives x-th soda a candy if he has one;
3. they just do nothing.

Now you are to determine whether it is possible and give a sequence of operations.
Input There are multiple test cases. The first line of input contains an integerT, indicating the number of test cases. For each test case:

The first contains an integer n
(1n105), the number of soda.
The next line contains n integers a1,a2,,an(0ai109), where ai denotes the candy i-th soda has.

Output For each test case, output "YES" (without the quotes) if possible, otherwise output "NO" (without the quotes) in the first line. If possible, then the output an integerm(0mn) in the second line denoting the number of operations needed. Then each of the followingm lines contain two integers x and y(1x,yn), which means that x-th soda gives y-th soda a candy.
Sample Input 3 6 1 0 1 0 0 0 5 1 1 1 1 1 3 1 2 3
Sample Output NO YES 0 YES 2 2 1 3 2
Author [email protected]
Source
Recommend wange2014   |   We have carefully selected several similar problems for you:  5994 5993 5992 5991 5990 

題目大意:

    有N過杯子,每一個有ai個糖果,每相鄰兩個之間可以最多傳遞一個糖果,問能不能最後每個杯子的糖果一樣多,並出處傳遞過程。

解題思路:

    這題的最基本思路和之前CF的一道題很像,就是把不正常的狀態按照一個方向傳遞給相鄰的轉態,使得這個狀態正常。

    首先,如果糖果總數不能被等分的話就一定錯誤,其次每個杯子最多給出或接受兩個糖果,如果其糖果數與平均值差的絕對值超過2也一定不可以。

    由於杯子形成了一個圈,所以糖果的傳遞一共只有兩種轉態,向前穿一個和向後傳一個。我們就可以使用貪心的思路從左到右掃,每次儘量使得當前被子達到要求。這樣一共三種情況,如果本來就達到要求了就跳過;如果多了就向右傳遞一個,如果少了就讓右邊的傳來一個。

    由於是一個環,所以我們還需要掃第二次,重複剛才的操作(注意可能會出現類似回溯的情況,要把上次的操作抵消掉)。這樣我們得到的結果就一定是正確的。最後判斷一下經過操作有沒有達到要求,輸出即可。

AC程式碼:

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <vector>
using namespace std;
#define LL long long
#define INF 0x3f3f3f3f
#define mem(a,b) memset((a),(b),sizeof(a))

const int MAXN=100000+3;
LL N,cup[MAXN];
bool l[MAXN],r[MAXN];//是否左移、右移

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%lld",&N);
        bool ok=true;
        LL ave=0;
        for(int i=0;i<N;++i)
        {
            scanf("%lld",&cup[i]);
            ave+=cup[i];
            l[i]=r[i]=false;
        }
        if(ave%N)//不能整除,一定不可以
        {
            puts("NO");
            continue;
        }
        ave/=N;
        for(int i=0;i<N;++i)
            if(cup[i]>ave+2||cup[i]<ave-2)//超過ave+2或小於ave-2,一定不可以
            {
                ok=false;
                break;
            }
        if(!ok)
        {
            puts("NO");
            continue;
        }
        
        for(int i=0;i<N;++i)
        {
            if(cup[i]>ave&&r[i]==false&&cup[(i+1)%N]<=ave)//右移
            {
                --cup[i];
                ++cup[(i+1)%N];
                if(l[(i+1)%N]==true)//和上次操作相抵消
                    l[(i+1)%N]=false;
                else r[i]=true;
            }
            else if(cup[i]<ave&&l[(i+1)%N]==false&&cup[(i+1)%N]>=ave)//左移
            {
                ++cup[i];
                --cup[(i+1)%N];
                if(r[i]==true)//和上次操作相抵消
                    r[i]=false;
                else l[(i+1)%N]=true;
            }
        }
        //第二輪
        for(int i=0;i<N;++i)
        {
            if(cup[i]>ave&&r[i]==false&&cup[(i+1)%N]<=ave)//右移
            {
                --cup[i];
                ++cup[(i+1)%N];
                if(l[(i+1)%N]==true)
                    l[(i+1)%N]=false;
                else r[i]=true;
            }
            else if(cup[i]<ave&&l[(i+1)%N]==false&&cup[(i+1)%N]>=ave)//左移
            {
                ++cup[i];
                --cup[(i+1)%N];
                if(r[i]==true)
                    r[i]=false;
                else l[(i+1)%N]=true;
            }
        }
        
        LL num=0;
        for(int i=0;i<N;++i)
        {
            if(cup[i]!=ave)//有的杯子不符合要求
            {
                ok=false;
                break;
            }
            if(l[i])
                ++num;
            if(r[i])
                ++num;
        }
        if(!ok)
            puts("NO");
        else
        {
            puts("YES");
            printf("%lld\n",num);
            for(LL i=0;i<N;++i)
            {
                if(r[i])
                    printf("%lld %lld\n",i+1,(i+1)%N+1);
                if(l[i])
                    printf("%lld %lld\n",i+1,(i-1+N)%N+1);
            }
        }
    }
    
    return 0;
}


相關推薦

HDU 5363 Average貪心+

Average Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 3032    Accepted Submi

HDU 5360 Hiking 貪心+優先佇列

There are n soda conveniently labeled by 1,2,…,n. beta, their best friends, wants to invite some soda to go hiking. The i-th soda will go hiking if the

HDU 2088 Box of Bricks

mit see after script move real order have ack 傳送門: http://acm.hdu.edu.cn/showproblem.php?pid=2088 Box of Bricks Time Limit: 1000/1000 MS

[HDU 5782] Cycle bitset優化+

HDU - 5782 給定兩個長度相等的字串 問他們的第 i個字首是否迴圈相等 迴圈相等的定義是,兩個長度相等的字串 其中一個字串能通過迴圈移位得到另一個 按照題解的說

hdu 5037 Frog貪心

2個 spa ble log pri scan string 需要 tar 題目鏈接:http://acm.split.hdu.edu.cn/showproblem.php?pid=5037 題解:為了讓放的石頭有意義肯定是沒l+1的距離放2個也就是說假設現在位置為

HDU 1257 最少攔截系統貪心 or LIS

分析 class mode arch urn namespace 最少攔截系統 雷達 mission 題目鏈接: http://acm.hdu.edu.cn/showproblem.php?pid=1257 最少攔截系統 Time Limit: 2000/1000 MS (

HDU - 6178:Monkeys 貪心&樹上最大匹配輸&輸入優化

xmlns input review possible tween math num monk include There is a tree having N vertices. In the tree there are K monkeys (K <= N). A

【牛客 - 210A】遊戲思維,

題幹: BLUESKY007,fengxunling和dreagonm三個人發現了一個畫素遊戲,這款神奇的遊戲每次會生成一個nxm的網格,其中每一個格子都被隨機染色為R,G,B三種顏色之一,每次都可以選擇任意一個非B顏色的格子進行一次操作,每次操作都會滿足以下規則: 1.操作的範圍為從整個網格的

HDU--4486 Task貪心

main 一個 一個數 pid sca 個數 lan efi scan 題目鏈接 4486 Task 按照時間從大到小排序 然後枚舉所有的y值 用一個數組存儲 符合要求就算上 #include<bits/stdc++.h> using namespa

HDU-Wooden Sticks貪心

Wooden Sticks There is a pile of n wooden sticks. The length and weight of each stick are known in advance. The sticks are to be processed by a wood

CF676E The Last Fight Between Human and AI特判

題意:現在給你一組多項式,給出一箇中間狀態,此時有些係數可能是確定的,有些係數可能是不確定的(用?表示),機器人和人將輪流為未知數設值(由於是中間狀態所以當前第一個設值的人不一定是機器人),給你整數k

HDU 4811 Ball貪心

題意: 給你三種顏色的球若干,讓你制定一個安防策略,使得你的分數最高分的規則是:當前安放的球前面的顏色的種類a+後面的顏色的種類b(不包括本身) 首先我們肯定是把球往中間放,如果能夠讓前面後面都有三種顏色的話,那剩下的球的分數都是固定的,所以說我們

補題:2018HUD暑期多校訓練第八場-From ICPC to ACMhdu-6408貪心+資料結構

題目大意: 給你k個月,告訴你每個月原材料的價格,使用者需求量,組裝電腦價格,公司最大產量 以及從本月到下一個月,電腦可存放量,原材料存放價格,電腦存放價格 求k個月下來,公司是否可以滿足使用者需求,如果可以輸出最小成本,否則輸出-1 解題思路:

hdu 2546 飯卡貪心+01揹包

飯卡 Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submissi

HDU 5360 Hiking優先隊列

maximum iss tle sta hit height oat spl play Hiking Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Other

hdu 5078 Osu!鞍山現場賽

math and accepted font size courier put mar trac Osu! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 262144/262144 K (Jav

HDU 3535 AreYouBusy組合背包

problem input clu include for each ted 錯誤 多少 line 傳送門 AreYouBusy Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K

NAT穿透UDP打

會有 work true icmp sea 類型判斷 無法 部分 什麽 1、NAT(Network Address Translator)介紹 NAT有兩大類,基本NAT和NAPT。 1.1、基本NAT 靜態NAT:一個公網IP對應一個內部IP,一對一轉換 動態NAT:N

HDU 5387 Clock分數類+模擬

textbox ica struct role 2.4 pac eal esp 2.3 題意: 給你一個格式為hh:mm:ss的時間,問:該時間時針與分針、時針與秒針、分針與秒針之間夾角的度數是多少。 若夾角度數不是整數,則輸出最簡分數形式

HDU 1695 GCD容斥定理

font hint cup show lan orm required stdio.h test case GCD Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/