以下是我对问题的实施:http://www.spoj.com/problems/ACODE/
#include <stdio.h>
#include <string.h>
int main() {
long long int dp[5010] = { 0 }, i, len, ans;
char str[5010];
scanf("%s", str);
while (str[0] != '0') {
len = strlen(str);
dp[0] =1;
for (i = 1; i < len; i++) {
ans = (str[i-1] * 10 + str[i]);
if (str[i] - '0')
dp[i] = str[i];
if (ans >= 10 && ans <= 26) {
if ((i - 2) < 0)
dp[i] += dp[0];
else
dp[i] += dp[i-2];
}
}
scanf("%s", str);
}
printf("%llu\n", dp[len-1]);
return 0;
}
当我在IDE中运行它时,它会被执行,但输出与预期完全不同。此外,当我在Ideone上运行时,它显示“超出时间限制”。请帮助我找出错误。
答案 0 :(得分:3)
有几个错误:
您只为最后一个字符串打印一次结果。当然,您应该打印所有字符串的结果。您的代码目前看起来像这样:
scanf("%s",str);
while (str[0] != '0') {
// determine solution
scanf("%s", str);
}
printf("%llu\n", dp[len-1]);
printf
应该在最后scanf
之前。
此:
ans = (str[i - 1] * 10 + str[i]);
是对ASCII码的计算。你需要这样的东西:
ans = ((str[i - 1] - '0') * 10 + str[i] - '0');
代码
if (str[i] - '0') dp[i] = str[i];
应该处理以零开头的子字符串,但它会使dp[i]
有效地未初始化(或填充前一个字符串中的垃圾)。
主要错误是你从错误的一端攻击问题。当你在字符串中前进时,你的算法就像这样:
if the next two digits are a number from 10 to 26:
dp[i] = dp[i + 1] + dp[i + 2]
else if the current digit isn't zero:
dp[i] = dp[i + 1]
else:
dp[i] = 0
该代码需要dp[j]
与j > i
的知识才能计算dp[i]
。这意味着您可以通过向后遍历数组来解决问题。然后,您的解决方案为dp[0]
。
因为你只期待一两个数字,所以你甚至不需要辅助数组;保留最后两个值并在每次迭代后相应地交换它就足够了。
这是一个解决方案。它仅针对给定的案例进行了测试,但它应该让您了解如何解决您的问题。代码没有做很多检查;假设字符串只有数字。
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
unsigned long long poss(const char *str)
{
unsigned long long p1, p2;
size_t len = strlen(str);
size_t i;
if (len == 0) return 0;
i = len - 1;
p1 = 1;
p2 = 1;
if (str[i] == '0') p1 = 0;
while (i-- > 0) {
unsigned long long p = p1;
if (str[i] == '0') p = 0;
if (str[i] == '1') p += p2;
if (str[i] == '2' && str[i + 1] < '7') p += p2;
p2 = p1;
p1 = p;
}
return p1;
}
int main(void)
{
char str[5001];
while(scanf("%s",str) == 1 && str[0] != '0') {
printf("%llu\n", poss(str));
}
return 0;
}
答案 1 :(得分:2)
你需要的是一个递归函数,如果你发现10到26之间的东西,它会分开
long long int count_decodings( const char * str )
{
long long int count = 1;
// only accept digits
// continue while next character greater or equal '0' and less or equal '9'
while ( ( *str >= '0' && *str <= '9' ) )
{
char actChar = *str;
str ++; // increment string pointer ( now str points to character after actChar )
if ( actChar == '1' && ( *str >= '0' && *str <= '9' ) )
{
// if we have 1 followed by somthing from 0 to 9 we have an new case
count += count_decodings( str + 1 ); // continue with next sign and increment count of decodings
}
else if ( actChar == '2' && ( *str >= '0' && *str <= '6' ) )
{
// if we have 2 followed by somthing from 0 to 6 we have an new case
count += count_decodings( str + 1 ); // continue with next sign and increment count of decodings
}
}
return count;
}
int main()
{
char str[5010];
scanf("%s",str);
while(str[0]!=0)
{
long long int count = count_decodings( str );
printf( "%llu\n", count);
scanf("%s", str);
}
return 0;
}