반응형

문제 출처 :


https://www.acmicpc.net/problem/1544



알고리즘 분석 :


문제 해결에 필요한 사항

1. Map STL


맵을 이용하여 문제를 풀어보자.


우선 이 문제의 핵심은 product가 있다면 productproduct로 스트링을 만들어 줘야한다.


왜냐면 그다음 문자열이 tproduc라면 productproduct에 걸리기 때문이다.


따라서 이 문제를 풀 때 맵을 2개를 만들되, 하나는 product가 있는 original인 맵을, 하나는 productproduct가 들어있는 맵을 만든다.


그리고 pair를 이용하여 값을 더 주는데 first에는 인덱스 번호를, second에는 productproduct의 원본 크기를 넣어준다.(여기선 7)


이제 for문을 보자.


첫번째 for문은 productproduct같은 연속된 문자열을 넣어둔 맵이고, 두번째 for문은 product같은 original 문자열이 있는 맵이다.


첫번째 if문에서 < 문자열 A,B의 인덱스가 다르면(복사된 문자열과 원래 문자열이 같은게 아니라면) > 이 나타난다.


즉, product와 productproduct는 당연히 검사에서 제외되어야 하니 인덱스가 다른 것들끼리 본다.


두번째 if문은 원래 문자열 길이 자체가 같다고 되어있는데 


예를들어 인풋이

2

a

aa라면

저 조건이 없으면 답은 1이 나오지만 실제로는 a와 aa는 엄연히 다르다. 따라서 답은 2가 나와야 하기에 저 코드가 있는 것이다.


즉, 초기 길이부터 같아야 같은 단어인지 파악하는 전제가 된다.


if, else if, else는 인덱스가 어떻게 구성되어있는지, 갱신을 해주는 방식이다.






소스 코드 : 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#include <iostream>
#include <cstdio>
#include <string>
#include <algorithm>
#include <map>
 
using namespace std;
 
typedef pair<intint> pii;
 
map<string, pii> mp;
map<string, pii> ori;
 
int main()
{
    int n;
    scanf("%d"&n);
 
    for (int i = 1; i <= n; i++)
    {
        string str;
        cin >> str;
 
        ori[str].first =  i;
        ori[str].second = str.size();
        int tmp = str.size();
 
        str += str;
        mp[str].first = i;        
        mp[str].second = tmp;
    }
 
    int cnt = -1;
    bool chk = false;
    for (auto it = mp.begin(); it != mp.end(); it++)
    {
        for (auto it2 = ori.begin(); it2 != ori.end(); it2++)
        {
            // 문자열 A,B의 인덱스가 다르면(복사된 문자열과 원래 문자열이 같은게 아니라면)
            if (it->second.first != it2->second.first)
            {
                // 이때 서로 원래 문자열 길이 자체가 같고, 원래 문자열이 복사된 문자열내에 존재할 경우
                if (it->second.second == it2->second.second && it->first.find(it2->first) != string::npos)
                {
                    // 이미 값이 존재하면 그 값을 대입, 그게 아니면 신규값 대입
                    if (it->second.first <= -1)
                        it2->second.first = it->second.first;
                    else if (it2->second.first <= -1)
                        it->second.first = it2->second.first;
                    else
                    {
                        it->second.first = cnt;
                        it2->second.first = cnt; 
                    }
 
                    chk = true;
                }
            }
        }
 
        // cnt가 이용된 경우에만 cnt--
        if (chk)
        {
            cnt--;
            chk = false;
        }
    }
 
    // 같은 인덱스 -> 중복되는 문자열들
    map<intint> ans;
    for (auto it = ori.begin(); it != ori.end(); it++)
        ans[it->second.first]++;
 
     cout << ans.size();
 
    return 0;
}
 
//                                                       This source code Copyright belongs to Crocus
//                                                        If you want to see more? click here >>
Crocus

반응형

'Applied > 알고리즘 문제풀이' 카테고리의 다른 글

[11407번] 책 구매하기  (0) 2017.12.08
[8992번] 집기 게임  (0) 2017.12.07
[11405번] 책 구매하기  (0) 2017.12.06
[3980번] 선발 명단  (0) 2017.12.06
[11409번] 열혈강호 6  (0) 2017.12.05