思维/构造 HDOJ 5353 Average

 

题目传送门

  1 /*
  2     思维/构造:赛后补的,当时觉得3题可以交差了,没想到这题也是可以做的。一看到这题就想到了UVA_11300(求最小交换数)
  3             这题是简化版,只要判断行不行和行的方案就可以了,做法是枚举x[1],x[n]的所有可能,x[2~n-1]能递推出来
  4             x[i]表示i给i+1的值(0/-1/1) 那么 a[i] - x[i] + x[i-1] == ave,详细看代码
  5 */
  6 /************************************************
  7 * Author        :Running_Time
  8 * Created Time  :2015-8-7 8:51:48
  9 * File Name     :A.cpp
 10  ************************************************/
 11 
 12 #include <cstdio>
 13 #include <algorithm>
 14 #include <iostream>
 15 #include <sstream>
 16 #include <cstring>
 17 #include <cmath>
 18 #include <string>
 19 #include <vector>
 20 #include <queue>
 21 #include <deque>
 22 #include <stack>
 23 #include <list>
 24 #include <map>
 25 #include <set>
 26 #include <bitset>
 27 #include <cstdlib>
 28 #include <ctime>
 29 using namespace std;
 30 
 31 #define lson l, mid, rt << 1
 32 #define rson mid + 1, r, rt << 1 | 1
 33 typedef long long ll;
 34 const int MAXN = 1e5 + 10;
 35 const int INF = 0x3f3f3f3f;
 36 const int MOD = 1e9 + 7;
 37 int a[MAXN];
 38 int x[MAXN];
 39 int n, tot;
 40 ll ave;
 41 
 42 bool work(void) {
 43     tot = 0;
 44     if (x[1] != 0)  tot++;
 45     if (x[n] != 0)  tot++;
 46     if (x[n-1] != 0)    tot++;
 47     for (int i=2; i<=n-2; ++i)  {
 48         if (abs (a[i] - ave + x[i-1]) > 1)  return false;
 49         x[i] = a[i] - ave + x[i-1];
 50         if (x[i] != 0)  tot++;
 51     }
 52     if (a[n-1] - x[n-1] + x[n-2] != ave)    return false;
 53     return true;
 54 }
 55 
 56 bool judge(void)    {
 57     for (int i=-1; i<=1; ++i)   {
 58         for (int j=-1; j<=1; ++j)   {
 59             x[1] = i, x[n] = j;
 60             if (abs (ave - a[n] + x[n]) <= 1)   {
 61                 x[n-1] = ave - a[n] + x[n];
 62                 if (work ())    return true;
 63             }
 64         }
 65     }
 66     return false;
 67 }
 68 
 69 int main(void)    {     //HDOJ 5353 Average
 70     int T;  scanf ("%d", &T);
 71     while (T--) {
 72         scanf ("%d", &n);   ll sum = 0;
 73         for (int i=1; i<=n; ++i)    {
 74             scanf ("%d", &a[i]);    sum += a[i];
 75         }
 76         if (sum % n != 0)   {
 77             puts ("NO");    continue;
 78         }
 79         ave = sum / n;   bool flag = true, same = true;
 80         for (int i=1; i<=n; ++i)    {
 81             if (a[i] < ave - 2 || a[i] > ave + 2)   {
 82                 flag = false;  break;
 83             }
 84             if (a[i] != ave)   same = false;
 85         }
 86         if (!flag)   {
 87             puts ("NO");    continue;
 88         }
 89         if (same)   {
 90             printf ("YES\n0\n");    continue;
 91         }
 92         
 93         memset (x, 0, sizeof (x));
 94         if (!judge ())  {
 95             puts ("NO");    continue;
 96         }
 97         puts ("YES");   printf ("%d\n", tot);
 98         for (int i=1; i<=n; ++i)    {
 99             if (x[i] == 0)  continue;
100             else if (x[i] == 1) printf ("%d %d\n", i, (i == n) ? 1 : i + 1);
101             else    printf ("%d %d\n", (i == n) ? 1 : i + 1, i);
102         }
103     }
104 
105     return 0;
106 }

 

posted @ 2015-08-07 10:12  Running_Time  阅读(240)  评论(0编辑  收藏  举报