Algorithm, Data structure/Solved Algorithmic Problem

USACO 2.2 - Party Lamps

JaykayChoi 2016. 7. 9. 16:13

To brighten up the gala dinner of the IOI'98 we have a set of N (10 <= N <= 100) colored lamps numbered from 1 to N.

The lamps are connected to four buttons:

  • Button 1: When this button is pressed, all the lamps change their state: those that are ON are turned OFF and those that are OFF are turned ON.
  • Button 2: Changes the state of all the odd numbered lamps.
  • Button 3: Changes the state of all the even numbered lamps.
  • Button 4: Changes the state of the lamps whose number is of the form 3xK+1 (with K>=0), i.e., 1,4,7,...

A counter C records the total number of button presses.

When the party starts, all the lamps are ON and the counter C is set to zero.

You are given the value of counter C (0 <= C <= 10000) and the final state of some of the lamps after some operations have been executed. Write a program to determine all the possible final configurations of the N lamps that are consistent with the given information, without repetitions.

PROGRAM NAME: lamps

INPUT FORMAT

No lamp will be listed twice in the input.

Line 1:N
Line 2:Final value of C
Line 3:Some lamp numbers ON in the final configuration, separated by one space and terminated by the integer -1.
Line 4:Some lamp numbers OFF in the final configuration, separated by one space and terminated by the integer -1.

SAMPLE INPUT (file lamps.in)

10
1
-1
7 -1

In this case, there are 10 lamps and only one button has been pressed. Lamp 7 is OFF in the final configuration.

OUTPUT FORMAT

Lines with all the possible final configurations (without repetitions) of all the lamps. Each line has N characters, where the first character represents the state of lamp 1 and the last character represents the state of lamp N. A 0 (zero) stands for a lamp that is OFF, and a 1 (one) stands for a lamp that is ON. The lines must be ordered from least to largest (as binary numbers).

If there are no possible configurations, output a single line with the single word `IMPOSSIBLE'

SAMPLE OUTPUT (file lamps.out)

0000000000
0101010101
0110110110

In this case, there are three possible final configurations:

  • All lamps are OFF
  • Lamps 1, 4, 7, 10 are OFF and lamps 2, 3, 5, 6, 8, 9 are ON.
  • Lamps 1, 3, 5, 7, 9 are OFF and lamps 2, 4, 6, 8, 10 are ON.



출처: http://train.usaco.org/



1부터 N 까지의 램프가 있다. 램프에 4개의 버튼이 있고 각각의 버튼은 다음과 같은 일을 한다.1

1: 모른 램프의 상태를 변경 (on -> off, off -> on)

2. 홀수 램프 상태 변경

3: 짝수 램프 상태 변경

4: 3k + 1 램프의 상태 변경


파티가 시작될 때 모든 램프는 켜져있습니다.

램프의 개수 N 과 버튼을 누를 횟수 C 그리고 최종적으로 켜져있어야 될 램프와 꺼져있어야 될 램프가 주어질 경우 가능한 모든 경우를 중복없이 구하시오.


input

1:  N

2: C

3: 켜져있어야 될 램프. 공백으로 구분되며 -1일 경우 종료

4. 꺼져있어야 될 램프. 공백으로 구분되며 -1일 경우 종료


output

꺼져있을 경우0, 켜져있을 경우 1, binary numbers 기준으로 오름차순으로 출력.

가능한 경우가 없을 경우 'IMPOSSIBLE' 출력.



처음에는 모든 경우를 구하는 brute force 방법을 사용했으나 c가 100인 상황에서 1초가 초과됬습니다. 그래서 다음 방법으로 c가 아무리 크더라도 결국 키고 끄는 행위를 반복할 뿐이라는 점을 이용해서 필요한 상황만 계산을 해서 풀었습니다.




my solving

c++

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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include <fstream>
#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <set>
using namespace std;
typedef long long ll;
 
ofstream fout("lamps.out");
int n;
vector<bool> lamps;
vector<int> on;
vector<int> off;
set<string> ret;
 
bool whetherMeet()
{
    for (vector<int>::iterator it = on.begin(); it != on.end(); it++)
    {
        if (lamps[*it] == false)
            return false;
    }
    for (vector<int>::iterator it = off.begin(); it != off.end(); it++)
    {
        if (lamps[*it])
            return false;
    }
 
    return true;
}
 
void changeState(int type)
{
    switch (type)
    {
    case 1:
        for (vector<bool>::iterator it = lamps.begin(); it != lamps.end(); it++)
            *it = !*it;
        break;
    case 2:
        for (int i = 0; i < n; i += 2)
            lamps[i] = !lamps[i];
        break;
    case 3:
        for (int i = 1; i < n; i += 2)
            lamps[i] = !lamps[i];
        break;
    case 4:
        for (int i = 0; i < n; i += 3)
            lamps[i] = !lamps[i];
        break;
    default:
        break;
    }
}
 
//It used more than the allotted runtime of 1 seconds when c is over 100
void bruteForce(int remainingNumber)
{
    if (remainingNumber == 0)
    {
        if (whetherMeet())
        {
            string str = "";
            for (int i = 0; i < n; i++)
                str += to_string((int)lamps[i]);
            ret.insert(str);
        }
        return;
    }
 
    for (int i = 1; i < 5; i++)
    {
        changeState(i);
        bruteForce(remainingNumber - 1);
        changeState(i);
    }
}
 
void greedy(int c)
{
    for (int i = 0; i < << 4; i++)
    {
        int type[4= { i & 1, i >> & 1, i >> & 1, i >> & };
        int bitCount = 0;
        for (int i = 0; i < 4; i++)
            bitCount += type[i];
 
        if (bitCount > c)
            continue;
 
        if (bitCount % != c & 2)
            continue;
 
        fill(lamps.begin(), lamps.end(), 1);
 
        for (int i = 0; i < 4; i++)
        {
            if (type[i] == 1)
                changeState(i + 1);
        }
 
        if (whetherMeet())
        {
            string str = "";
            for (int i = 0; i < n; i++)
                str += to_string((int)lamps[i]);
            ret.insert(str);
        }
    }
}
 
int main()
{
    ifstream fin("lamps.in");
    
    int c;
    fin >> n >> c;
 
    int lamp;
    while (fin >> lamp)
    {
        if (lamp == -1)
            break;
        on.push_back(lamp - 1);
    }
    while (fin >> lamp)
    {
        if (lamp == -1)
            break;
        off.push_back(lamp - 1);
    }
 
    vector<bool> temp(n, 1);
    lamps = temp;
 
    greedy(c);
 
 
    if (ret.empty())
    {
        fout << "IMPOSSIBLE" << endl;
    }
    else
    {
        for (set<string>::iterator it = ret.begin(); it != ret.end(); it++)
            fout << *it << endl;
    }
 
    fin.close();
    fout.close();
    return 0;
}
cs



'Algorithm, Data structure > Solved Algorithmic Problem' 카테고리의 다른 글

BAEKJOON 1003 - 파보나치 함수  (0) 2016.07.10
BAEKJOON 1002 - 터렛  (0) 2016.07.10
USACO 2.2 - Runaround Numbers  (0) 2016.07.08
USACO 2.2 - Subset Sums  (0) 2016.07.07
USACO 2.2 - Preface Numbering  (0) 2016.07.07