POJ1250解题报告补

参考我前一篇文章有详细解析

上篇我写的文章

关于本篇

在这篇里,我对POJ1250想到了新的解题方法,同时在使用新方法的时候调试了许多有意思的bug,与诸君分享

新方法思路

我用specialized二值数组去接看出现的字符是否为第一次出现,如果第一次出现,就把specialized[s[i]-'A']置为true,(这里用了技巧,用大写字符减去‘A’得到唯一的一个数字)
然后再判断是否房间空,房间不空就把trek[s[i-'A']]置为true,这样就标志着s[i]入住了,如果不入住就把ans++,ans存储离开的人数
详细看着代码思考,这里只是简单介绍

代码

#include <iostream>
#include <string>
using namespace std;
#define max 100
bool specialized[max];
bool trek[max];
int main()
{
    int n;
    string s;
    while(cin>>n &&n){
        cin>>s;
        memset(specialized,false,sizeof(specialized));//这两行代码不能放错地方
        memset(trek,false,sizeof(trek));
        int ans=0;   //初始化ans
        for(int i=0;i<s.length();i++){
            if(!specialized[s[i]-'A']){
                specialized[s[i]-'A']=true;
                if(n>0){
                    trek[s[i]-'A']=true;
                    n--;
                    continue;
                }
                else {
                    ans++;
                    continue;
                }
            }
            if(specialized[s[i]-'A']){ //判断第二次出现是住的客人还是离开的客人
                if(trek[s[i]-'A']){
                    n++;
                }
            }
        }   
        if(!ans) cout<<"All customers tanned successfully."<<endl;
        else cout<<ans<<" customer(s) walked away."<<endl;
    }
    return 0;
}
上个版本实测通过,同时还有很多版本,比如说对里面的if-else 进行修改啥的。。。

又想到一个可以AC的版本,故放之于博客
代码:

#include <iostream> //亮点已经加注释
#include <string>
using namespace std;
#define max 257 //因为字符ASCII码值不会大于255,所以定义为257即可满足
bool specialized[max];
bool trek[max];
int main()
{
    int n;
    string s;
    while(cin>>n &&n){
        cin>>s;
        memset(specialized,false,sizeof(specialized));
        memset(trek,false,sizeof(trek));
        int ans=0;
        for(int i=0;i<s.length();i++){
            if(!specialized[s[i]]){//每个字符ASCII码值唯一,故可以这么存储,这里的s[i]是指字符s[i]的ASCII码值,下面同
                specialized[s[i]]=true;
                if(n>0){
                    trek[s[i]]=true;
                    n--;
                    continue;
                }
                else {
                    ans++;
                    continue;
                }
            }
            if(specialized[s[i]]){
                if(trek[s[i]]){
                    n++;
                }
            }
        }   
        if(!ans) cout<<"All customers tanned successfully."<<endl;
        else cout<<ans<<" customer(s) walked away."<<endl;
    }
    return 0;
}
下面是找bug过程,各位有兴趣的小伙伴可以去想一下为什么这些代码过不了?

思考题找bug

以下代码都是博主自己在AC过程中改错的代码,觉得错的比较有意思,故拿出来和诸君分享,各位有兴趣可以去试一下为什么错了。(答案附在文章最后)

代码1:

#include <iostream>
#include <string>
using namespace std;
#define max 100
bool specialized[max];
bool trek[max];
int main()
{
    int n;
    string s;
    while(cin>>n &&n){
        cin>>s;
        memset(specialized,false,sizeof(specialized));
        memset(trek,false,sizeof(trek));
        int ans=0;
        for(int i=0;i<s.length();i++){
            if(!specialized[s[i]-'A']){
                specialized[s[i]-'A']=true;
                if(n>0){
                    trek[s[i]-'A']=true;
                    n--;
                }
                else {
                    ans++;
                }
            }
            if(specialized[s[i]-'A']){
                if(trek[s[i]-'A']){
                    n++;
                }
            }
        }   
        if(!ans) cout<<"All customers tanned successfully."<<endl;
        else cout<<ans<<" customer(s) walked away."<<endl;
    }
    return 0;
}

代码2:

#include <iostream>
#include <string>
using namespace std;
#define max 100
bool specialized[max];
bool trek[max];
int main()
{
    int n;
    string s;
    memset(specialized,false,sizeof(specialized));
    memset(trek,false,sizeof(trek));
    while(cin>>n &&n){
        cin>>s;
        int ans=0;
        for(int i=0;i<s.length();i++){
            if(!specialized[s[i]-'A']){
                specialized[s[i]-'A']=true;
                if(n>0){
                    trek[s[i]-'A']=true;
                    n--;
                    continue;
                }
                else {
                    ans++;
                    continue;
                }
            }
            if(specialized[s[i]-'A']){
                if(trek[s[i]-'A']){
                    n++;
                }
            }
        }   
        if(!ans) cout<<"All customers tanned successfully."<<endl;
        else cout<<ans<<" customer(s) walked away."<<endl;
    }
    return 0;
}

代码3:

#include <iostream>
#include <string>
using namespace std;
#define max 100
bool specialized[max];
bool trek[max];
int main()
{
    int n;
    string s;
    memset(specialized,false,sizeof(specialized));
    memset(trek,false,sizeof(trek));
    while(cin>>n &&n){
        cin>>s;
        int ans=0;
        for(int i=0;i<s.length();i++){
            if(!specialized[s[i]-'A']){
                specialized[s[i]-'A']=true;
                if(n>0){
                    trek[s[i]-'A']=true;
                    n--;
                }
                else {
                    ans++;
                }
            }
            if(specialized[s[i]-'A']){
                if(trek[s[i]-'A']){
                    n++;
                }
            }
        }   
        if(!ans) cout<<"All customers tanned successfully."<<endl;
        else cout<<ans<<" customer(s) walked away."<<endl;
    }
    return 0;
}

思考题解答

代码1:错在for循环中的两个if在上个if执行玩了之后specialized的值会更改,所以下面那个if可能会执行,这样导致结果错误。

代码2:specialized,trek布尔数组初始化地方不对,按那种写法,第二次输入字符串再判断的时候会用到第一次字符串的判断留下的在specialized和trek数组的结果,所以要在每次循环时都初始化一下

代码3:代码1和代码2的综合错误

还有说个题外话:

if-else 结果可以用 if结构加上 continue来代替
另外if(!flag) 等价于 if(flag==0) 

end

                                seen
                                2015-09-14

你可能感兴趣的:(数组,bug,poj,调试)