Student. CSE

백준 랜덤마라톤 #18

백준 랜덤마라톤 #18 문제풀이

image

BOJ 25756 [B3] - 방어율 무시 계산하기

  • 단순계산 문제
#include <bits/stdc++.h>
using namespace std;

int main(void){
    cin.tie(0)->sync_with_stdio(0);
    int N;
    double V = 0.0;

    cin >> N;
    cout.fixed;
    cout.precision(10);
    while(N--){
        double A; cin >> A;
        V= (1-((1-(0.01*V))*(1-(0.01*A))))*100;
        cout << V <<"\n";
    }
}

BOJ 30111 [S4] - 겹다각형의 각

  • 여러번 도형을 그려가면서 일반화를 시키다보면 다음을 얻을 수 있음.
  • 처음 각의 합은 (처음 각의 개수-2)*180
  • 두번째부터는 처음각의 합에 (각의 개수)*180
#include <bits/stdc++.h>
using namespace std;

int main(void){
    cin.tie(0)->sync_with_stdio(0);
    int N;
    cin >> N;
    vector<int> k(N);
    for(auto &i : k) cin >> i;
    reverse(k.begin(),k.end());
    int A = (k[0]-2)*180;

    for(int i = 1; i<k.size();i++){
        A+= 180*k[i];
    }
    cout << A <<"\n";
}

BOJ 31672 [S3] - 특별한 케이크 (easy)

  • 실버문제이기는 하나, 난이도는 골드급이었음
  • i번째의 정보를 저장후에 , i번 차례인 경우 해당 정보만 뒤집은 후, i번의 정보가 담긴 모든 수가 1 (범인) 인 경우에만 범인 리스트에 넣었음
#include <bits/stdc++.h>
#include <cstdio>

using namespace std;

int main(void){
    string str;
    getline(cin, str);
    int N; cin >> N;
    vector< vector<int> > d(N+1, vector<int>(2,0));
    vector<pair<vector<int>, int>> Q(N+1);
    for(int i = 1; i<=N;i++){
        int M; cin >> M;
        vector<int> S(N+1,0);
        while(M--){
            int s; cin >> s;
            S[s] = 1;
        }
        int j; cin >> j;
        Q[i] = {S,j};
        for(int i = 1 ;i<=N;i++){
            d[i][(j==1?S[i] : !S[i])]++;
        }
    }
    vector <int> ans ;

    for(int i = 1; i<=N;i++){
        int k = Q[i].first[i];
        if(Q[i].second == 1) (k = k == 0 ? 1 : 0);
        int z = d[i][0];
        int o = d[i][1];
        if(k == 0){
            z++;
            o--;
        }
        else{
            z--;
            o++;
        }
        if(z == 0) ans.push_back(i);
        
    }
    if(ans.empty()) cout << "swi";
    else{
        sort(ans.begin(), ans.end());
        for(auto i : ans ) cout << i <<" ";
    }

}

BOJ 18291 [G5] - 비요뜨의 징검다리 건너기

  • 큰수의 거듭제곱 문제와 동일

#include <bits/stdc++.h>

using namespace std;
int fast_pow(int x, int n, int m){
	if(n == 0) return 1 % m;
	long long u = fast_pow(x,n>>1, m);
	u = (u*u)%m;
	if(n&1) u = (u*x)%m;
	return u;
}
int main(void){
	cin.tie(0)->sync_with_stdio(0);
	int T, N;
	cin >> T;
	while(T--){
		cin >> N;
		if(N == 1) cout << 1 <<"\n";
		else cout << fast_pow(2,N-2,(int)1e9+7) <<"\n";
	}
}

BOJ 17498 [G5] - 폴짝 게임

  • NM 의 최대만 나와있으므로, iM +j 로 카운팅 해주는 방법을 생각할 수 있음
  • DP 문제
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;

ll INF = 1e12;
int N, M , D;
ll a[200200];
ll d[200200];


ll dp(int cur){

	if(cur  >= N*M ) return -INF;
	int x = cur / M;
	int y = cur % M;

	if(x == N-1) return 0;
	ll &ret = d[cur];

	if(ret != -INF) return ret;
	for(int i = x+1; i<=x+D;i++){
		for(int j = y-D; j<= y+D;j++){
			if((0<=i && i<N && 0<=j && j<M) && (abs(i-x)+abs(j-y) <= D)){
				ret = max(ret, a[cur]*a[i*M+j] + dp(i*M+j));
			}
		}
	}
	return ret;
}

int main(void){
	cin >> N >> M >> D;

	for(int i = 0;i <N;i++){
		for(int j = 0; j<M;j++){
			cin >> a[i*M+j];
			d[i*M+j] = -INF;
		}
	}
	ll ans = -INF;
	for(int i = 0;i<M;i++) ans = max(ans, dp(i));
	cout << ans <<"\n";

}

BOJ 19597 [G5] - 문자열 뒤집기

  • S[i][0] 에는 뒤집히지 않은 문자열, S[i][1]에는 뒤집힌 문자열 저장
  • 최대한 사전순으로 앞에 와야하므로, dfs 를 이용하여 접근가능
#include <bits/stdc++.h>

using namespace std;
typedef long long ll;


string rv(const string& s){
	string ret = s;
	reverse(ret.begin(),ret.end());
	return ret;
}

int main(void){
	cin.tie(0)->sync_with_stdio(0);
	int T, N;
	cin >> T;
	while(T--){
		cin >> N;
		vector<vector<string>> S(N,vector<string>(2));
		vector<int> d(N);
		for(int i = 0;i<N;i++) {
			cin >> S[i][0];
			S[i][1] = rv(S[i][0]);
		}
		bool f = true;
		auto DP = [&](int cur, auto&& DP){
			if(cur == N){
				for(auto i : d) cout << i;
				f = false;
				return;
			}
			for(int i = 0; f && i<2;i++){
				if(cur == 0|| S[cur -1][d[cur-1]] <= S[cur][i] ){
					d[cur] = i;
					DP(cur+1,DP);
				}
			}
		};
		DP(0,DP);
		cout <<"\n";
	}

}

BOJ 9177

  • DP 문제
  • 두 단어의 인덱스를 인자로 하여, 생성문자열 R과 같은 지 비교하면서 풀어야함
#include <bits/stdc++.h>
using namespace std;

int main(void){
	cin.tie(0)->sync_with_stdio(0);
	int T; cin >> T;
	string A,B,R;
	int d[303][303];
	auto dfs = [&](int a, int b, auto&& dfs)-> bool {
		if(a == A.size() && b == B.size()) return true;

		auto &ret = d[a][b];
		if(ret != -1) return ret;
		if(a < A.size() && A[a] == R[a+b] && dfs(a+1,b,dfs)) ret =true ;
		else if(b<B.size() && B[b] == R[a+b] &&  dfs(a,b+1,dfs)) ret =true;
		else ret = false;
		return ret;
	};

	for(int tc = 1; tc<=T;tc++){

		cin >> A >>B >>R;
		memset(d,-1,sizeof(d));
		cout <<"Data set "<< tc <<": "<< (dfs(0,0,dfs) ? "yes" : "no")<<"\n";

	}
}

BOJ 16947 [G3] - 서울 지하철 2호선

  • Cycle을 찾은 후에 BFS로 cycle과의 거리를 측정하면 됨
#include <bits/stdc++.h>
using namespace std;

int main(void){
	cin.tie(0)->sync_with_stdio(0);

	int N;
	cin >> N;
	vector<int> g[3003];
	for(int i = 0;i<N;i++){
		int u,v; cin >> u >> v;
		g[u].push_back(v);
		g[v].push_back(u);
	}
	vector<bool> visited(N+1,false);
	vector<bool> isCycle(N+1,false);
	int prev[3003];
	bool flag = false;
	auto _cycle = [&](int cur,auto&& _cycle){
		visited[cur] = true;

		for(auto i : g[cur]){
			if(flag) return;
			if(visited[i]){
				if(i != prev[cur]){
					isCycle[cur] = true;
					flag = true;
					while(cur != i){
						isCycle[prev[cur]] = true;
						cur = prev[cur];
					}
					return;
				}
			}
			else{
				prev[i] = cur;
				_cycle(i,_cycle);
			}
		}
	};
	_cycle(1,_cycle);

	for(int i = 1; i<=N;i++){
		if(isCycle[i]) cout << "0 " ;
		else{

			vector<int> dst(N+1,0);
			vector<bool> vst(N+1,false);
			queue <int> Q;
			int p = 0;
			Q.push(i);

			while(!isCycle[Q.front()]){
				int c = Q.front();
				Q.pop();
				vst[c] = true;
				for(auto u : g[c]){
					if(vst[u]) continue;
					dst[u] = dst[c] +1;
					Q.push(u);
				}
			}
			cout << dst[Q.front()] <<" ";
		}

	}

}