Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[백트래킹] 9월 30일 #7

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions 15661.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int permutation(vector<bool> num, int n, vector<vector<int>> stat){
int ans = 2000;

for(int i=0; i<n/2; i++){
num[i] = true;
}
Comment on lines +11 to +13
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

지금 이 문제는 "두 팀의 인원수는 같지 않아도 되지만, 한 명 이상이어야 한다." 이 조건으로 인해 딱 절반으로 팀을 나눠서는 안돼요! 예를 들어 총 7명이라면 팀이 (1/6) (2/5) (3/4) 로 나뉘는 모든 경우를 고려해야 해요.
현재 문제에 제출하면 '맞았습니다'가 뜨긴 하지만, 아마 문제에 테스트케이스가 부족한 것 같아요. 따라서 꼭 코드 수정 해주세요!


do{
int l_total = 0, s_total = 0;
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
if(num[i] && num[j])
l_total += stat[i][j];
else if(!num[i] && !num[j])
s_total += stat[i][j];
}
}
Comment on lines +17 to +24
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

조합으로 풀어주셨네요! 아주 좋아요~! 이 부분은 함수화를 해봐도 좋을 것 같아요! 더불어 여유가 되시면 백트래킹으로도 푸신 후, 시간을 비교해 보아도 좋을 것 같아요!

ans = min(ans, abs(l_total-s_total));
}while(prev_permutation(num.begin(), num.end()));

return ans;
}

int main(){
int n;
cin >> n;
vector<vector<int>> stat(n, vector<int>(n, 0));
for(int i=0; i<n; i++){
for(int j=0; j<n; j++){
cin >> stat[i][j];
}
}

vector<bool> num(n, false);

cout << permutation(num, n, stat);

return 0;
}
44 changes: 44 additions & 0 deletions 15665.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@

#include <iostream>
#include <set>
#include <vector>

using namespace std;

int n, m;
vector<int> temp(7);
set<vector<int>> out;

void backtracking(int cnt, vector<int> nums){
if(cnt == m){
out.insert(temp);
return;
}
Comment on lines +13 to +16
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

p1. 가능한 수열을 모두 만든 후, 중복 수열을 거르는 것보다, 애초에 중복 수열이 만들어지지 않도록 탐색하는 방법이 있어요! 지금 수열의 중복이 생기는 이유는 무엇일까요? 입력으로 꼭 서로 다른 숫자가 들어오지 않고 있어요. 중복 수를 미리 처리한 후, 백트래킹을 돌려볼까요!


for(int i=0; i<n; i++){
temp[cnt] = nums[i];
backtracking(cnt+1, nums);
}
}

int main(){

cin >> n >> m;

vector<int> nums(n);
for(int i=0; i<n; i++){
cin >> nums[i];
}

backtracking(0, nums);

for(auto it=out.begin(); it != out.end(); it++){
vector<int> t = *it;
for(int j=0; j<m; j++){
cout << t[j] << ' ';
}
cout << '\n';
}

return 0;
}
61 changes: 61 additions & 0 deletions 2529.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int n;
vector<char> gl;
string s;
vector<string> ans;
bool check[10];
int name[10];

void backtracking(int cnt, int prev, char c){
if(cnt == n+1){
s = "";
for(int i=0; i<=n; i++){
s += to_string(name[i]);
}
ans.push_back(s);
return;
}

if(c == '<'){
for(int i=prev+1; i<10; i++){
if(!check[i]){
check[i] = true;
name[cnt] = i;
backtracking(cnt+1, i, gl[cnt]);
check[i] = false;
}
}
}
else if(c == '>'){
for(int i=0; i<prev; i++){
if(!check[i]){
check[i] = true;
name[cnt] = i;
backtracking(cnt+1, i, gl[cnt]);
check[i] = false;
}
}
}
Comment on lines +24 to +43
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오! 이 탐색법은 처음 보는데 좋네요!! 👍

더불어 이 문제는 가능한 모든 수열을 구하지 않고, 바로 최솟값과 최댓값을 구할 수 있어요! 최솟값과 최댓값이 어떤 수로 이루어지는지 생각해볼까요?

}

int main(){

cin >> n;

for(int i=0; i<n; i++){
char ch;
cin >> ch;
gl.push_back(ch);
}

backtracking(0, -1, '<');
sort(ans.begin(), ans.end());

cout << ans.back() << '\n' << ans.front();

}