user-0 提问: 求助一道简单的acm试题

回复:
user: user-1
content: 引用 27 楼 weixin_41259211 的回复:[quote=引用 26 楼 FancyMouse的回复:]你们哪里来的信心32位int能存的下答案。输入如果是3w个Q，3w个A，再3w个Q呢 改成long以后也不行，答案是错误的[/quote] 不好意思，只考虑逻辑，类型用错了，把int改成long吧(不确定你用的什么编译器，建议还是改成long long吧)，把最后输出也一并改了：printf("%ld\n", ...)或printf("%lld\n"...)。改完再试试呢。(nums类型最好也改了，5w*4w会超int)

user: user-0
content: 引用 26 楼 FancyMouse的回复:你们哪里来的信心32位int能存的下答案。输入如果是3w个Q，3w个A，再3w个Q呢 改成long以后也不行，答案是错误的

user: user-2
content: 你们哪里来的信心32位int能存的下答案。输入如果是3w个Q，3w个A，再3w个Q呢

user: user-0
content: 引用 24 楼 weixin_41259211的回复:[quote=引用 22 楼 _暮雨潇湘_的回复:] #include <stdio.h> #include <string.h>  #define MAXN (100000+2)  char input[MAXN]; int  nums[MAXN];  // 注意左结合 // 先计算能结合出多少个'AQ' // 再计算能结合出多少个'QAQ'  // 求每个'A'后面跟了多少个'Q' void calc_q_nums_after_a(char* s, int n, int* nums) { 	int i, num = 0; 	for (i = n-1; i >= 0; i--) { 		if (s[i] == 'Q') { 			num++; 		} else if (s[i] == 'A') { 			nums[i] = num; // 第一步收割, 'Q'左结合'A'得到'AQ'数量 		} 	} }  // 求'QAQ'出现次数 int calc_qaq_nums(char* s, int n, int* nums) { 	int i, aq = 0, qaq = 0; 	for (i = n-1; i >= 0; i--) { 		if (s[i] == 'A') { 			aq += nums[i]; // 到现在为止出现'AQ'的数量 		} else if (s[i] == 'Q') { 			qaq += aq; // 第二步收割, 'AQ'左结合'Q'得到'QAQ'的数量 		} 	} 	return qaq; }  int main(void) { 	scanf("%s", input); 	int n = strlen(input); // O(n) 	calc_q_nums_after_a(input, n, nums); // O(n) 	printf("%d\n", calc_qaq_nums(input, n, nums)); // O(n) 	return 0; }   试试这样呢？ 为什么会有编译错误的提示，我感觉是对的！[/quote] 不对，我修改了下，可以运行了 但是答案错误

user: user-0
content: 引用 22 楼 _暮雨潇湘_的回复: #include <stdio.h> #include <string.h>  #define MAXN (100000+2)  char input[MAXN]; int  nums[MAXN];  // 注意左结合 // 先计算能结合出多少个'AQ' // 再计算能结合出多少个'QAQ'  // 求每个'A'后面跟了多少个'Q' void calc_q_nums_after_a(char* s, int n, int* nums) { 	int i, num = 0; 	for (i = n-1; i >= 0; i--) { 		if (s[i] == 'Q') { 			num++; 		} else if (s[i] == 'A') { 			nums[i] = num; // 第一步收割, 'Q'左结合'A'得到'AQ'数量 		} 	} }  // 求'QAQ'出现次数 int calc_qaq_nums(char* s, int n, int* nums) { 	int i, aq = 0, qaq = 0; 	for (i = n-1; i >= 0; i--) { 		if (s[i] == 'A') { 			aq += nums[i]; // 到现在为止出现'AQ'的数量 		} else if (s[i] == 'Q') { 			qaq += aq; // 第二步收割, 'AQ'左结合'Q'得到'QAQ'的数量 		} 	} 	return qaq; }  int main(void) { 	scanf("%s", input); 	int n = strlen(input); // O(n) 	calc_q_nums_after_a(input, n, nums); // O(n) 	printf("%d\n", calc_qaq_nums(input, n, nums)); // O(n) 	return 0; }   试试这样呢？ 为什么会有编译错误的提示，我感觉是对的！

user: user-3
content: 这个好像可以...

user: user-0
content: 引用 7 楼 weixin_41259211的回复:[quote=引用 6 楼 MyCout的回复:]   我觉得num统计数量时应该放在    if(p[i]=='Q'||p[i]=='A')         {             a[n]=p[i];             n++;         } 里面，当前num的统计值是超过Q,A数量的，后面的内存是未知的，可能会出现问题，我用你的程序测试了下，一般情况值是正确的。 放到里面以后你测试了吗？[/quote] 放到里面就是时间超限，我觉得算法有问题

user: user-0
content: 引用 6 楼 MyCout的回复:我觉得num统计数量时应该放在    if(p[i]=='Q'||p[i]=='A')         {             a[n]=p[i];             n++;         } 里面，当前num的统计值是超过Q,A数量的，后面的内存是未知的，可能会出现问题，我用你的程序测试了下，一般情况值是正确的。 放到里面以后你测试了吗？

user: user-0
content: 引用 1 楼 学习编程的萌新的回复:同学你看看我这个  我也是初学者 #include<iostream> #include<cstring> using namespace std; char s[100005];  int main(){ 	int i,j,len,k,cnt=0;  	cin>>s; 	len = strlen(s); 	for(i=0;i<len;i++){ 		if(s[i]=='Q') 		for(j=i+1;j<len;j++){ 			if(s[j]=='A') 			for(k=j+1;k<len;k++){ 				if(s[k]=='Q') 				cnt++; 			} 		} 	} 	cout<<cnt<<endl; 	return 0; } 额  看了   时间超限的错误

user: user-0
content: 引用 1 楼 学习编程的萌新的回复:同学你看看我这个  我也是初学者 #include<iostream> #include<cstring> using namespace std; char s[100005];  int main(){ 	int i,j,len,k,cnt=0;  	cin>>s; 	len = strlen(s); 	for(i=0;i<len;i++){ 		if(s[i]=='Q') 		for(j=i+1;j<len;j++){ 			if(s[j]=='A') 			for(k=j+1;k<len;k++){ 				if(s[k]=='Q') 				cnt++; 			} 		} 	} 	cout<<cnt<<endl; 	return 0; } 代码不全啊，再发一遍看看￣ ￣

user: user-0
content: 引用 2 楼 MyCout的回复:值不对还是？ 值不对，我已经发现了算法有问题，但不知道怎么修改了

user: user-4
content: 我觉得num统计数量时应该放在    if(p[i]=='Q'||p[i]=='A')         {             a[n]=p[i];             n++;         } 里面，当前num的统计值是超过Q,A数量的，后面的内存是未知的，可能会出现问题，我用你的程序测试了下，一般情况值是正确的。

user: user-1
content: #include <stdio.h> #include <string.h>  #define MAXN (100000+2)  char input[MAXN]; int  nums[MAXN];  // 注意左结合 // 先计算能结合出多少个'AQ' // 再计算能结合出多少个'QAQ'  // 求每个'A'后面跟了多少个'Q' void calc_q_nums_after_a(char* s, int n, int* nums) { 	int i, num = 0; 	for (i = n-1; i >= 0; i--) { 		if (s[i] == 'Q') { 			num++; 		} else if (s[i] == 'A') { 			nums[i] = num; // 第一步收割, 'Q'左结合'A'得到'AQ'数量 		} 	} }  // 求'QAQ'出现次数 int calc_qaq_nums(char* s, int n, int* nums) { 	int i, aq = 0, qaq = 0; 	for (i = n-1; i >= 0; i--) { 		if (s[i] == 'A') { 			aq += nums[i]; // 到现在为止出现'AQ'的数量 		} else if (s[i] == 'Q') { 			qaq += aq; // 第二步收割, 'AQ'左结合'Q'得到'QAQ'的数量 		} 	} 	return qaq; }  int main(void) { 	scanf("%s", input); 	int n = strlen(input); // O(n) 	calc_q_nums_after_a(input, n, nums); // O(n) 	printf("%d\n", calc_qaq_nums(input, n, nums)); // O(n) 	return 0; }   试试这样呢？

user: user-5
content: 刚那个复杂度1e15，估计也会超时 比如QAQJLZBBQ，实际对你有用的只有QAQQ，所以处理后变为1001. 实际你可以把一个完整的串分为三个部分，第一部分的1的数目*第二部分的0的数目*第三部分的1的数目，当你把所有的分法遍历之后就是总的个数了。 假设处理之后是第三部分是01011，第一部分确定的情况下，那么numAQ（第二部分的0的数目*第三部分的1的数目）的所有分法总和是1*3+1*2+2*2+2*1，当左边是新加一个0时，numAQ先加个3，再所有左加数加一，实际加了了3+3+2+2+1，这个数字就是二三部分右起第0到第5，4，3，2，1个部分1的总数，算的话应该是右起第0到第4，3，2，1个部分1的总数+右起第0到第4的1的总数加0（因为新加的不是1），同理如果左边再加个0，只需要NumAQ+Num1，1也是一样的，这样时间复杂度就是1e5了，过程能懂的话算法多写几次就行了

user: user-0
content: 引用 19 楼 user-5的回复:新建一个bool[]，Q为true，A为False，其余全部丢掉；              for(int i = 0; i < n; i++)             {                 if (a[i])                 {                     for(int j = i + 1; j < n; j++)                     {                         if (!a[j])                         {                             for (int k = j + 1; k < n; k++)                             {                                 if (a[k])                                 {                                     num++;                                 }                             }                         }                     }                 }             } 额，不太明白，新手，能把代码给我看看学习下吗

user: user-5
content: 新建一个bool[]，Q为true，A为False，其余全部丢掉；              for(int i = 0; i < n; i++)             {                 if (a[i])                 {                     for(int j = i + 1; j < n; j++)                     {                         if (!a[j])                         {                             for (int k = j + 1; k < n; k++)                             {                                 if (a[k])                                 {                                     num++;                                 }                             }                         }                     }                 }             }

user: user-4
content: 我感觉这问题我就不太了解了 有测试用例还可以了解哈

user: user-0
content: 引用 16 楼 MyCout的回复:/*#include <stdlib.h> 开始这句 你把/*去掉再使用的吧  不然编译都不会过 嗯....这点我还是知道的，去掉了

user: user-4
content: /*#include <stdlib.h> 开始这句 你把/*去掉再使用的吧  不然编译都不会过

user: user-0
content: 引用 14 楼 MyCout的回复:你可以把平台测试错误相关的信息发出来比较好 不然信息太少了 我的是时间超限（但我知道算法有问题了），楼上那个算法是答案错误，网站只给了这两个信息