Encoding
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 38854 Accepted Submission(s): 17224
Problem Description
Given a string containing only 'A' - 'Z', we could encode it using the following method:
1. Each sub-string containing k same characters should be encoded to "kX" where "X" is the only character in this sub-string.
2. If the length of the sub-string is 1, '1' should be ignored.
1. Each sub-string containing k same characters should be encoded to "kX" where "X" is the only character in this sub-string.
2. If the length of the sub-string is 1, '1' should be ignored.
Input
The first line contains an integer N (1 <= N <= 100) which indicates the number of test cases. The next N lines contain N strings. Each string consists of only 'A' - 'Z' and the length is less than 10000.
Output
For each test case, output the encoded string in a line.
Sample Input
2 ABC ABBCCC
Sample Output
ABC A2B3C
大体内容:先输入整数N,代表要判断几行字符,然后再输入几行字符,分别判断这些字符中各个字符出现的此数,注意只有紧挨着的字符才算在一起,比如AABBAABB这样还是算2A2B2A2B。
虽然看起来不难,但是自己还是遇到了不小的困难,两次修改代码都是Time Limit Exceeded,先贴这两次Time Limit Exceeded的代码再分析:
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int main()
{
char a[500]; //存放输入的字符串
char b[500]; //对应为存放出现过的字符
int c[500]; //对应为存放出现过的字符的个数
int T; //用来标志输入多少个字符串
int flag=0; //用来标记当前查找字符的位置
int tag=0; //用来标记是否已经找到了字符的末尾
memset(a,0,500);
memset(b,0,500);
cin>>T;
while(T--)
{
cin>>a;
char d; //当前查找的字符
for(int i=0;i<strlen(a);i++)
{
d=a[i];
int f=1; //某一类字符出现的个数
if(tag)break; //已经找到了最后一个,直接退出
if(i<strlen(a)-1)
{
for(int j=i+1;j<strlen(a);j++)
{
if(a[j]==d)f++;
else {
i=j-1;
b[flag]=d;
c[flag]=f;
break;
}
if(j==strlen(a)-1) //判断是否查找到最后一个,如果查找到,就将所查找的结果返回给存放的数组
{
tag=1;
b[flag]=d;
c[flag]=f;
break;
}
}
flag++;
}else {
b[flag]=d;
c[flag]=f;
flag++;
}
}
for(int y=0;y<flag;y++) //输出
{
if(c[y]!=1)cout<<c[y]<<b[y];
else cout<<b[y];
}
cout<<endl;
}
return 0;
}
第一遍自己写的比较复杂,总的来说出现的问题还不小,存放字符串的长度在1~10000,自己定义的字符串只有500,这显然是不对的,不过最重点还是自己的字符在查找
时时间超了1s,原因还是自己使用了两层循环,时间复杂度太大了。然后贴自己第二遍修改的代码:
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int main()
{
char a[10001]; //存放输入的字符串
memset(a,0,10001);
int T;
cin>>T;
while(T--)
{
char temp;
int count=1;
cin>>a;
int n=strlen(a);
for(int i=0;i<n;i++)
{
temp=a[i];
while(a[i++]==a[i])
{
count++;
}
if(count!=1)cout<<count<<temp;
else cout<<temp;
i--;
count=1;
}
}
return 0;
}
看起来代码量少了一点,但是本质上还是没有改变自己使用两层循环,时间复杂度还是没有改变,依旧超时,郁闷。。。。。。。贴自己最终意识到这个问题之后修改的代码:
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
int main()
{
char a[10001]; //存放输入的字符串
memset(a,0,10001);
int T;
cin>>T;
while(T--)
{
char temp;
int count=1;
cin>>a;
int n=strlen(a);
temp=a[0];
for(int i=1;i<n;i++)
{
if(temp==a[i])
{
count++;
}
else if(count!=1)
{
cout<<count<<temp;
count=1;
temp=a[i];
}
else
{
cout<<temp;
count=1;
temp=a[i];
}
}
if(count!=1)cout<<count<<temp; //别忘了最后还有一组字符没输出
else cout<<temp;
cout<<endl;
}
return 0;
}
这次就很简单了,用if-else语句从前往后判断,而不是使用循环嵌套,这样时间复杂度只有O(n)了,完全符合要求。