hdu4038——成都网络赛1008

这两天跟1008过不去额。。。老是被一些2b类型的错误卡。。。。

周六1008因为函数参数里一个long long的失误悲剧,周日的1008因为没有添加新生成的数到数组中一直WA。。。。这后台数据够强的~~

思路:如果有奇数个负数,找出最大的那个,一直往上调,到0为止,然后把尽可能把0变成1,然后尽可能把1变成2,2->3.。。。到最后剩下的m求pow(3,m/3)然后填到数组里排序(注意,一定要填到数组里,否则后面的步骤可能出错,我就在这里WA了n次。。。),然后如果m%3还剩1的话,就把数组中最小的一个数加1(知道为什么前面那步要先填到数组里了吧,就是这。。。),否则最后的结果乘2。

#include <iostream>
#include
<cstdio>
#include
<cstring>
#include
<algorithm>
using namespace std;

const int N = 100100;

typedef
long long llg;

const llg P = 1000000007;

int n, a[N];
llg m;

llg pow(llg a, llg b)
{
llg tmp
= a%P, ans = 1;
while(b)
{
if(b & 1) ans = ans * tmp % P;
tmp
= tmp*tmp % P;
b
>>= 1;
}
return ans%P;
}

int main()
{
int T, Case = 0;
int ct, i;
llg ans;
freopen(
"data.txt", "r", stdin);
scanf(
"%d", &T);
while(T--)
{
scanf(
"%d%I64d", &n, &m);
for(i = 0; i < n; i++) scanf("%d", a+i);
sort(a, a
+n);
for(i = ct = 0; i < n; i++)
{
ct
+= (a[i]<0);
if(a[i] >= 0) break;
}
if(ct & 1)
{
i
--;
if(-a[i] <= m)
{
m
+= a[i];
a[i]
= 0;
}
else
{
a[i]
+= m;
m
= 0;
}
}
for(i = 0; i<n && m>0; i++)
if(a[i] == 0)
{
a[i]
++;
m
--;
}
for(i = 0; i<n && m>0; i++)
if(a[i] == 1)
{
a[i]
++;
m
--;
}
for(i = 0; i<n && m>0; i++)
if(a[i] == 2)
{
a[i]
++;
m
--;
}
ans
= 1;
if(m >= 3)
{
a[n]
= pow(3, m/3);
n
++;
m
%= 3;
}
sort(a, a
+n);
if(m == 1)
{
for(i = 0; i < n; i++)
if(a[i] > 0)
{
a[i]
++;
break;
}
}
else if(m == 2)
ans
= ans * 2 % P;
for(i = 0; i < n; i++)
ans
= ans * a[i] % P;
printf(
"Case %d: %I64d\n", ++Case, ans);
}
return 0;
}

  

你可能感兴趣的:(HDU)