前言
哇,关于这题,我真的有好多话说!!!首先,我这清奇的脑回路,在学暴力求解法这章,但是我的思路并不是暴力解题(好吧其实是因为一开始觉得暴力求解好麻烦,数据量大),花了两个小时把握的思路实现,但是WA了。
第一次调试的时候,终于发现了数据溢出了,数据真的好容易溢出,数据真的好容易溢出,数据真的好容易溢出!!!
最大值是1e+18,那这时候采用long long int就可以解决问题了,int 为 4 字节(数据表示范围:二进制32位,即-231——231-1,约为2 X 109),long long int 为8字节(数据表示范围:二进制64位,即-263——263-1,约为9 X 1018),但是,还是一直WA。。。啊它痛击我。。。。
然后,把它丢在一边,看剧去了。。。
下午4点的时候,找了一下uDebug上的一组数据,比对了一下,发现了隐藏及其深的Bug!一改,终于OK了。
我想着,如果自己多写几组测试数据,会不会惊喜地找出这个bug,但是这是小概率事件,但是但是,也不是不可能hhh。
题目
思路
1、将输出的数据根据0,分隔成二维数组。
2、记录每行数据的负数的个数。
3、若个数为偶数,则对应行全部连乘上,得出该行的最大值。
4、若个数为奇数,则枚举各个起点,乘到 (个数-1)个负数,即当乘到最后一个负数时即结束,比较各个max得出该行的MAX。
5、比较每行的MAX,得出结果。
我的思路比较奇葩吧,看完暴力求解的思路,发现此处数据量不大,枚举子序列的起点和终点就行了。(其实我一开始也有差不多想到这个,为什么说差不多呢,因为我当时不知道如何确定乘到什么时候停下来,因为负数的负负得正…)现在总结当时为什么一票否决了这个,是因为我不知道连续子序列的要素就是 起点、终点呀,那就相当于枚举组合数了呀。
也就我的代码2000多了,没谁了哈哈哈哈哈哈哈哈哈哈哈哈
AC代码
在vjudge上一直出不了结果,就去了UVa原网站提交,还是那个味儿,网速还是那么感人(捂脸)
对了,还有,直接枚举起点和终点的代码往下翻,刷刷刷5分钟就写完了…(捂脸哭)
//@author reasonbao
//2020/3/21
//9:00-11:01 + WA后调试了半小时 + uDebug上找测试数据调试
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int kMaxn = 20;
int main() {
// freopen("uva_11059_data_in.txt","r",stdin); //输入重定向,输入数据将从该文件读取
// freopen("uva_11059_data_out.txt","w",stdout); //输出重定向
int n;
int kase = 0;
while (cin >> n) {
kase++;
// if (kase > 1) cout << endl; //打印空行
int s[kMaxn][kMaxn];
int count_row = 0;
//初始化二维数组
for (int i = 0; i < kMaxn; i++) {
for (int j = 0; j < kMaxn; j++) {
s[i][j] = 0;
}
}
//由0分割,将一维数组转为二维数组
int last_tmp = 0;
int is_empty = 1;
for (int i = 0, j = 0 ,k = 0; i < n; i++) {
int tmp;
cin >> tmp;
if (tmp == 0) {
//二维数组非空、不是连续出现0 ,数组行下移
if (!is_empty && last_tmp) {
j++;
k = 0;
}
}
else {
s[j][k++] = tmp;
is_empty = 0;
}
count_row = j+1;
last_tmp = tmp;
}
// for (int i = 0; i < kMaxn; i++) {
// for (int j = 0; j < kMaxn; j++) {
// cout << s[i][j] << " ";
// }
// cout << endl;
// }
// cout << "count_row = " << count_row << endl;
int count_negative[kMaxn];
memset(count_negative, 0, sizeof(count_negative));
// for (int i = 0; i < kMaxn; i++) cout << count_negative[i];
for (int i = 0; i < count_row; i++) {
for (int j = 0; s[i][j]; j++) {
if (s[i][j] < 0) {
count_negative[i]++;
}
}
}
// for (int i = 0; i < kMaxn; i++) cout << count_negative[i];
long long int max_arr[kMaxn]; //记录每一行的最大值
// int max_arr[kMaxn]; //记录每一行的最大值 Wrong Answer 越界咯,当18个元素均为10的情况下,答案为1e+18,int不够
for (int i = 0; i < count_row; i++) {
max_arr[i] = s[i][0]; //每行的最大值,初始化为第一个元素的值
if (count_negative[i] % 2 == 0) { //负数个数为偶数,全乘上
for (int j = 1; s[i][j]; j++) {
max_arr[i] *= s[i][j];
}
}
else { //负数个数为奇数(记为n)的情况,乘到n-1个奇数时停。 再取最大的那个
for (int j = 0; s[i][j]; j++) {
int count_neg = 0;
long long int max_tmp = s[i][j];
// if (s[i][0] < 0) count_neg++; 阿西,找到BUG了终于
if (s[i][j] < 0) count_neg++;
for (int k = j+1; s[i][k] && count_neg <count_negative[i]; k++) {
if (s[i][k] < 0) count_neg++;
if (count_neg == count_negative[i]) break;
max_tmp = max_tmp * s[i][k];
}
if (max_tmp > max_arr[i]) max_arr[i] = max_tmp;
}
}
}
// for (int i = 0; i < count_row; i++) {
// cout << "max = " << max_arr[i] << endl;
// }
//数据全是0的情况——二维数组为空
long long int ans = 0;
if (is_empty) {
ans = 0;
}
else {
sort(max_arr, max_arr+count_row);
ans = max_arr[count_row-1];
if (ans <= 0) ans = 0;
}
printf("Case #%d: The maximum product is %lld.\n\n", kase, ans);
}
return 0;
}
/*
10 0 0 1 2 -3 0 0 -1 2 0
*/
AC代码2.0(刷刷刷5分钟写完…)
#include <iostream>
#include <cstdio>
using namespace std;
long long int Operate(int *s, int begin, int end) {
long long int max = s[begin];
for (int i = begin+1; i <= end; i++) { //注意,这里是<=end,end是数组下标
max *= s[i];
}
return max;
}
int main() {
int n;
int s[20];
int kase = 0;
while (cin >> n) {
kase ++;
for (int i = 0; i < n; i++) {
cin >> s[i];
}
long long int ans = 0;
//枚举起点和终点
for (int i = 0; i < n; i++) {
for (int j = i; j < n; j++) {
// cout << "begin = " << i << " end = " << j << endl;
// cout << "ans = "<< Operate(s,i,j) << endl;
if (Operate(s,i,j) > ans) ans = Operate(s,i,j);
}
}
if (ans <= 0) ans = 0;
printf("Case #%d: The maximum product is %lld.\n\n", kase,ans);
}
return 0;
}
END
——————————————————————
Say say it again
说,再说一遍
Sometimes the memory was winding my mind
有时记忆缠绕在我的脑海中
——Say it again
——————————————————————