[풀이]백준 풀이(XVII/6603 등)
문제풀이
[RE]로또(6603, DFS)
- 로또는 1~49에서 숫자를 6개 고른다.
- 49개 중 K(>6)개를 골라 그 수로 번호를 선택하는 전략이 있다.
- K개를 골랐을 때 나올 수 있는 모든 순열을 구하시오.
회고
- 아주 기본 DFS인데 구현이.. 제대로 안되었다.
- 쉽게생각해라 쉽게쉽게…
#include<iostream>
#define MAX_SIZE 13
using namespace std;
int lotto[MAX_SIZE];
int combi[MAX_SIZE];
int k;
void dfs(int start, int depth) {
if(depth == 6) { //탈출조건
for(int i=0; i<6; i++) {
cout << combi[i] << ' '; //조합하나를 출력한 뒤 탈출
}
cout << '\n';
return;
}
for(int i=start; i<k; i++) { //lotto배열 0부터 k-1까지 탐색함
combi[depth] = lotto[i]; //depth는 깊이 -> 0~5번째 깊이까지 재귀를통해 새로 탐색한 숫자를 넣음.
dfs(i+1, depth+1); //재귀 들어가는 부분 , 하나의 깊이를 탐색 후 저장했으니 다음 함수호출할때는 깊이+1을 해줘야함.
}
}
int main() {
while(cin >> k && k) { //0을 입력 받을 때 까지 무한루프
for(int i=0; i<k; i++) {
cin >> lotto[i];
}
dfs(0,0);
cout << '\n';
}
return 0;
}
스타트와 링크(14889, 기출)
- 총 N명이 모였다 N/2씩 팀을 두개 이룬다(N=짝수)
- 능력치 S(i,j)는 i번사람과 j번사람이 같은 팀이 되었을 때 팀에 더해지는 능력치이다.
-
팀의 능력치는 S(i,j) + S(j,i) 들의 합이다.
- 두 팀의 능력차이를 최소로하게 팀을 나누고 싶다.
- 4<= N <= 20
- S(i,i) = 0
- S(i,j) <=100
회고
- 디버깅하는데 시간을 너무 많이 쓴다..
- 조합관련된 문제를 풀 때 크게 도움이 될 것 같다.
#include<iostream>
#include<vector>
#include<queue>
#include<algorithm>
#define INF 987654321
using namespace std;
int n,m;
int s[20][20];
int teamA=INF, teamB=INF, aTmp=0, bTmp=0, Answer = INF;
int start[10], link[10];
vector<int> human;
vector<int> helper;
vector<int> synergyA;
vector<int> synergyB;
vector<int> twoA;
vector<int> twoB;
//n명중 n/2를 뽑아서 계산한다?
void calcA(){
//A팀의 최소값을 구하자
do{
int x, y;
queue<int> tmp;
for(int i=0; i<m; i++){
if(twoA[i]==1){
tmp.push(synergyA[i]);
}
}
while(!tmp.empty()){
x = tmp.front(); tmp.pop();
y = tmp.front(); tmp.pop();
//cout<< "team A is " << x << " " << y << " " << "and synergy is " << s[x][y] << " and " << s[y][x] << endl;
aTmp += (s[x][y] + s[y][x]);
}
}while(next_permutation(twoA.begin(), twoA.end()));
}
void calcB(){
//B팀의 최소값을 구하자
do{
int x, y;
queue<int> tmp;
for(int i=0; i<m; i++){
if(twoB[i]==1){
tmp.push(synergyB[i]);
}
}
while(!tmp.empty()){
x = tmp.front(); tmp.pop();
y = tmp.front(); tmp.pop();
//cout<< "teamB is " << x << " " << y << " " << "and synergy is " << s[x][y] << " and " << s[y][x] << endl;
bTmp += (s[x][y] + s[y][x]);
}
}while(next_permutation(twoB.begin(), twoB.end()));
}
int main(){
cin >> n;
m = n/2;
for(int i=0; i<m; i++){
if(i==0 || i==1) {
twoA.push_back(1);
twoB.push_back(1);
}
else {
twoA.push_back(0);
twoB.push_back(0);
}
}
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
cin >> s[i][j];
}
human.push_back(i);
if(i%2==0) helper.push_back(0);
else helper.push_back(1);
}
sort(human.begin(), human.end());
sort(helper.begin(), helper.end());
sort(twoA.begin(), twoA.end());
sort(twoB.begin(), twoB.end());
//팀을 나누고
do{
int idxA = 0;
int idxB = 0;
for(int i=0; i<helper.size(); i++){
if(helper[i] ==1){
synergyA.push_back(human[i]);
start[idxA]= human[i];
idxA++;
}
else{
synergyB.push_back(human[i]);
link[idxB] = human[i];
idxB++;
}
}
sort(synergyA.begin(), synergyA.end());
sort(synergyB.begin(), synergyB.end());
// cout << "teamA is ";
// for(int i=0; i<m; i++){
// cout << synergyA[i] << " ";
// }
// cout << endl;
// cout << "teamB is ";
// for(int i=0; i<m; i++){
// cout << synergyB[i] << " ";
// }
// cout << endl;
calcA();
calcB();
// cout << "A synergy is " << aTmp << endl;
// cout << "B synergy is " << bTmp << endl;
Answer = min(Answer, abs(aTmp-bTmp));
if(Answer==0) break;
aTmp = 0;
bTmp = 0;
synergyA.clear();
synergyB.clear();
}while(next_permutation(helper.begin(), helper.end()));
cout << Answer;
}
댓글남기기