백준문제풀이
백준 문제 3151번 합이 0 문제풀이 c++
노가다 김씨
2022. 3. 28. 19:01
https://www.acmicpc.net/problem/3151
3151번: 합이 0
Elly는 예상치 못하게 프로그래밍 대회를 준비하는 학생들을 가르칠 위기에 처했다. 대회는 정확히 3명으로 구성된 팀만 참가가 가능하다. 그러나 그녀가 가르칠 학생들에게는 큰 문제가 있었다.
www.acmicpc.net
문제해석
그냥 N이 최대 10000개이고 4초 제한이라 N^2으로 풀릴거같아서 별 생각 안하고 브루트포스 방법을 사용했다.
먼저 N개중에 2개를 뽑아서 더한 값을 x라고 하면 선택하지 않은 것중 -x가 있는지 없는지 확인했다.
코드에서 p는 양수 m은 음수이다.
예를들어 p[36]=2 이면 36이 2개란 뜻이고 m[24]=5 이면 -24가 5개란 뜻이다.
근데 귀찮게 이렇게 안하고 map 사용하면 되는데 작성할땐 이게 먼저 생각났나보다.
게다가 중복일때 경우의 수를 올리는 작업을 안해야 했는데
그거 안해도 시간안에 통과할것 같기도 하고 좀 어려워서 작성하지않았다.
때문에 같은 경우가 3!=6만큼 생기므로 최종답에서 6을 나누어주었다.
코드
#include <iostream>
#include <algorithm>
#include <vector>
#include <cmath>
typedef long long int ll;
using namespace std;
void dfs(ll depth,ll sum);
bool visited[10005];
ll p[10005];
ll m[10005];
ll a[10005];
ll n;
ll ans=0;
int main(){
cout.tie(NULL);
cin.tie(NULL);
ios_base::sync_with_stdio(false);
cin>>n;
for(ll i=0; i<n; i++)
{
cin>>a[i];
if(a[i]>=0)
{
p[a[i]]++;
}
else
{
m[-a[i]]++;
}
}
if(n<3)
{
cout<<"0\n";
}
else
{
dfs(0,0);
cout<<ans/6<<"\n";
}
}
void dfs(ll depth,ll sum){
if(depth==2)
{
if(0<=abs(sum)&&abs(sum)<=10000)
{
if(sum>0)
{
ans=ans+m[sum];
}
else if(sum<0)
{
ans=ans+p[-sum];
}
else
{
ans=ans+p[0];
}
}
return;
}
for(ll i=0; i<n; i++)
{
if(visited[i]==0)
{
if(a[i]>=0)
{
visited[i]=1;
p[a[i]]--;
dfs(depth+1,sum+a[i]);
p[a[i]]++;
visited[i]=0;
}
else
{
visited[i]=1;
m[-a[i]]--;
dfs(depth+1,sum+a[i]);
m[-a[i]]++;
visited[i]=0;
}
}
}
}