sdnu1099

 
#include <iostream>
#include <set>
#include <string>


using namespace std;
int main()
{
    set<string> str1;                               //储存字符串片段
    set<string> str2;                               //储存不同字符串
    set<string> str4;                               //储存不同字符串中不是前缀的
    string str[1001];
    string sts[1001];                               //储存相同字符串
    int n, i, k, l1 = 0, sign = 0;
    string in1, in2;
    set<string>::iterator it1;
    set<string>::iterator it2;
    cin >> n;
    for(i = 0; i < n; i++)
    {
        cin >> in1;
        //判断是否是str2已存在的字符
        if(str2.insert(in1).second == false)
        {
            str[l1] = in1;                       //输入的相同字符
            l1++;
        }
        else
        {
            str2.insert(in1);                           //输入的不同字符
            //对于不同字符进行拆解
            for(k = 1; k < in1.size(); k++)
            {
                in2.assign(in1.c_str(), k);
                str1.insert(in2);                       //每一种拆解后的字符串片段
            }
        }
    }
    int flog;
    for(it2 = str2.begin(); it2 != str2.end(); it2++)
    {
        flog = 0;
       // cout << *it2 << endl;
        for(it1 = str1.begin(); it1 != str1.end(); )
        {


            if(*it1 == *it2)
            {
                flog = 1;
                sign++;
                break;
            }
            else
                it1++;
        }
        if(flog == 0)
            str4.insert(*it2);
    }
    set<string>::iterator it4;
    int x = 0;
    for(i = 0; i < l1; i++)
    {
        for(it4 = str4.begin(); it4 != str4.end(); it4++)
        {
            if(str[i] == *it4)
            {
                sts[x] = *it4;
                x++;
                break;
            }
        }
    }
    l1 -= x;
    sign += l1 + 2 * x;
    cout << sign << endl;
    return 0;
}

上面是我写的,下面是师哥写的。。。

 

正确的:

#include<set>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>


using namespace std;


const int MAXN = 1000+10;
int vis[1000+10];
int main()
{
    int n, ans = 0;
    string s[MAXN];
    scanf("%d", &n);
    set<string> ss;
    memset(vis, 0, sizeof(vis));
    for(int i = 0; i < n; i++){
		cin>>s[i];
		for(int k = 1; k < s[i].length(); k++){
			if(!ss.count(s[i].substr(0,k)))
				ss.insert(s[i].substr(0,k));
		}
	}
    for(int i = 0; i < n; i++){
		if(ss.count(s[i])){
		   ans++;
		   vis[i] = 1;
		}
	}
    for(int i = 0; i < n; i++){
        if(vis[i] == 1)
            continue;
        for(int j = 0 ; j < n ; j++){
            if(i == j)
                continue ;
            if(s[i] == s[j]){
                ans++;
                break;
            }
        }
    }
	printf("%d\n",ans);
    return 0;
}

 

其中count函数和substr函数是十分重要的:

 

count:

count(目标串,目标串+n(想找的范围), x(找哪个) )

这个函数用来判断x在目标串中出现的次数;

sunstr:

str.sunstr(x,y)

这个函数用来取str中从x到y之间的字符。

 

最近看了前缀树,感觉用前缀树也能做。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值