思维/构造 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 }
编译人生,运行世界!