HDOJ 5353 Average 模拟

各种情况特判,然后枚举前两个点之间的关系

Average

Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)

Total Submission(s): 1723    Accepted Submission(s): 438

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 soda x 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 integer T,
indicating the number of test cases. For each test case:

The first contains an integer n (1≤n≤105),
the number of soda.

The next line contains n integers a1,a2,…,an (0≤ai≤109),
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 integer m (0≤m≤n) in
the second line denoting the number of operations needed. Then each of the following m lines
contain two integers x and y (1≤x,y≤n),
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

Source

2015 Multi-University Training Contest 6

/* ***********************************************
Author        :CKboss
Created Time  :2015年08月08日 星期六 09时35分46秒
File Name     :HDOJ5353.cpp
************************************************ */

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <cmath>
#include <cstdlib>
#include <vector>
#include <queue>
#include <set>
#include <map>

using namespace std;

typedef long long int LL;

const int maxn=100100;

int n;
int a[maxn],b[maxn],f[maxn];
LL s;

void print()
{
	puts("YES");
	int cnt=0;
	for(int i=0;i<n;i++)
		if(f[i]) cnt++;
	printf("%d\n",cnt);
	for(int i=0;i<n;i++)
	{
		int nx=i+1;
		if(nx==n) nx=0;
		if(f[i]==1)
		{
			printf("%d %d\n",i+1,nx+1);
		}
		else if(f[i]==-1)
		{
			printf("%d %d\n",nx+1,i+1);
		}
	}
}

bool func(int x)
{
	memcpy(b,a,sizeof(a));
	memset(f,0,sizeof(f));

	f[0]=x;
	b[0]-=x; b[1]+=x;
	b[n]=b[0];

	for(int i=1;i<n;i++)
	{
		if(abs(b[i])>=2) return false;
		if(b[i]==1)
		{
			f[i]=1;
			b[i]-=1;
			b[i+1]+=1;
		}
		else if(b[i]==-1)
		{
			f[i]=-1;
			b[i]+=1;
			b[i+1]-=1;
		}
	}
	return true;
}

int main()
{
	//freopen("in.txt","r",stdin);
	//freopen("out.txt","w",stdout);

	int T_T;
	scanf("%d",&T_T);
	while(T_T--)
	{
		scanf("%d",&n);
		s=0;
		for(int i=0;i<n;i++)
		{
			scanf("%d",a+i);
			s+=a[i];
		}
		if(s%n!=0) { puts("NO"); continue; }
		s=s/n;
		bool fg=true;
		bool zero=true;
		for(int i=0;i<n&&fg;i++)
		{
			a[i]-=s;
			if(a[i]!=0) zero=false;
			if(!(a[i]>=-2&&a[i]<=2)) fg=false;
		}

		if(fg==false) { puts("NO"); continue; }
		if(zero==true) { puts("YES\n0"); continue; }

		if(func(0)) print();
		else if(func(1)) print();
		else if(func(-1)) print();
		else puts("NO");
	}

    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-06 06:22:48

HDOJ 5353 Average 模拟的相关文章

思维/构造 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 /**********************************************

hdu5353 Average(模拟)

转载请注明出处: http://www.cnblogs.com/fraud/          ——by fraud Average Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 1457    Accepted Submission(s): 360Special Judge Problem Description There ar

HDOJ 5071 Chat 模拟

大模拟: 1>saygoodbye要先对 always on top 的人说 2>对没有说过话的不要说good bye 3>用long long Chat Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 337    Accepted Submission(s): 82 Problem Description As ever

HDU 5353 Average(平分值,求步聚)多校6

Average Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Total Submission(s): 1948    Accepted Submission(s): 495 Special Judge Problem Description There are n soda sitting around a round table. soda are numbered

HDU 5353—— Average——————【贪心+枚举】

Average Time Limit: 4000/2000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others)Total Submission(s): 2069    Accepted Submission(s): 517Special Judge Problem Description There are n soda sitting around a round table. soda are numbered fr

HDU 5353 Average

题意:有n个人坐在圆桌上,每个人带着糖果若干,每次只能给旁边的人1科糖果,而且坐相邻的两个人最多只能给一次(要么你给我,要么我给你),问是否能将糖果平均分了. 思路:明显每个人最多只能多于平均值2个糖果,因为他只能分别往左和右边的人给1颗.而多于平均值1的人可以任意选1个方向,只要到最后所有人满足了即可.多余糖果超过3的.平均数是浮点型的都是无解. 在第i和第i+1个人之间建两条边(即无向边拆成2条有向边),分别从一方指向另一方.1和n也建两条.分两步: (1)将持有2个多余糖果的人先处理,用D

HDOJ 4690 EBCDIC 模拟

把图片用ORC转化成文字,用vim录个宏很容易就可以字母们格式化..... EBCDIC Time Limit: 2000/2000 MS (Java/Others)    Memory Limit: 102400/102400 K (Java/Others) Total Submission(s): 811    Accepted Submission(s): 368 Problem Description A mad scientist found an ancient message fr

HDU 5353 Average 贪心

就是贪心啊,不知道为啥总是不过,总是WA 方法不对吗? 将数组扩展一倍,从左到右扫描,大于平均数就给右边的,小于就从右边拿,等于就不变,记录下操作类型. 大于2直接NO,应该是正确的算法吧,自己出了一些数据也都过了 1 #pragma comment(linker, "/STACK:102400000,102400000") 2 #include <iostream> 3 #include <cstdio> 4 #include <fstream>

hdoj 5319 Painter(模拟题)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5319 思路分析:假设颜色R表示为1,颜色B表示为2,颜色G表示为3,因为数据量较小,采用暴力解法即可,即每次扫描对角线,看每条对角线需要画多少笔,统计所有对角线的笔数和即可: 代码如下: #include <cstdio> #include <cstring> #include <iostream> using namespace std; const int MAX_N