题目:
有一个数列,所有的数都是非负整数,你可以进行如下方式进行一次操作(注意一次完整的操作必须先后完成如下两个步骤):
(1) 任选一个不小于3的数,把它减少3。
(2) 任选一个数把它增加1。
请问,最多能够操作多少次?
输入格式:
多组数据,每组数据第一行是一个正整数n,表示数列中数的个数。(1<=n<=20000)
第二行包含n个空格分隔的非负整数,每个整数不超过1000000。
输出格式:
对每组数据输出一行,表示最多可以进行的操作次数。
输入样例
1
10
2
10 11
输出样例:
4
10
题目分析:
1、加入数列中的每一个数都是3的倍数,那么要想得到最大次数,那么所有数最终转移到同一个数上。
2、对于K%3 !=0的,首先应尽量将K%3==2的先转换成K%3==0的数,然后 消除K%3==1的,最后按照1中的处理。
因此,可以吧数列中的每个数划分到余数为:1,2,4,0集合中。
static string cal(int[] array)
{
string result = "";
int[] ra = new int[5];
int count = 0;
#region 首先将数据全部初始化为1,2,4,3的集合,表示个数
for (int i = 0; i < array.Length; i++)
{
switch (array[i] % 3)
{
case 0:
ra[0] += array[i] / 3;
break;
case 1:
if (array[i] > 4)
{
count += 2;
ra[0] += (array[i] - 4) / 3;
}
else
{
if (array[i] == 1)
{
ra[1]++;
}
else
{
ra[4] += 1;
}
}
break;
case 2:
if (array[i] > 2)
{
count++;
ra[0] += (array[i] - 2) / 3;
}
else
{
ra[2]++;
}
break;
}
}
#endregion
#region 消去原则:首先消去余数为2的,同时又会产生新的
if (ra[0]> 0)
{
//余数为0的个数大于1的时候,2,4的个数可以全部消去
count += ra[4] * 2 + ra[2];
count += cal(ra[0], ra[1]);
}
else
{
if(ra[4]>0&&ra[4]+ra[2]>1)
{
count += (ra[4] - 1) * 2 + ra[2] + 1;
}
else
{
if(ra[4]>0)
{
count ++;
}
}
}
#endregion
result = count.ToString();
return result;
}
//这个方法其实可以直接计算出结果
static int cal(int zero, int one)
{
int count = 0;
if (zero == 0)
{
return 0;
}
if (zero >= one * 2)
{
count = one * 2;
zero = zero - one;
if (zero > 0)
{
if (zero % 2 == 0)
{
count += (zero * 3 - 6) / 2 + 2;
}
else
{
count += (zero * 3 - 3) / 2 + 1;
}
}
}
else
{
if (zero % 2 == 0)
{
zero = zero / 2;
one = one - zero;
count += zero;
}
else
{
one = one - zero / 2;
count += (zero - 1);
zero = zero / 2 + 1;
}
count += cal(zero, one);
}
return count;
}
-3+1-c#求解-英雄会在线编程题目,布布扣,bubuko.com
原文:http://blog.csdn.net/mamihong/article/details/24019585