Noip 시뮬레이션 (9)을 행사
- 쉽게. 한 AK.
운동 프로그램
기술
- 몸은 혁명의 수도 때문이 아니라 강한 연구 및 건강의 비용으로 하루 종일 컴퓨터 앞에 OIers
건강 문제. X 작은 디자인 자신의 운동 프로그램은, 그러나 그는 계획 즉, 가능 여부를 알지 못했다
가난한 계획은 자신의 힘 오버런을 할 수 있다면, 그래서 작은 x는 그를 도와하시기 바랍니다.
어느 날 1440 분, 이렇게 작은 X의 목록을 하루 1 ~ 1440 분의 계획.
물리적으로 작은 정수와 X, 그는 동시에, 분당 작은 X, 일정에 따라 행사할 것이라고 말했다
체력이 자동으로 하나씩 증가됩니다. 분 작은 x의 물리적 끝이 제로보다 작은 경우, 그 불쌍한 x는 경우
에를 착용 ......
입력
- 첫 번째 라인은 공간 분리 된 두 정수 N m이며, 각각은 소형의 X 초기 계획 물리량 나타내는
항목 번호.
M 개의 행에서 시작하는 제 2 선로가, 각 행은 운동 프로그램 설명 이름, 시작 시간, 끝
간 B를 프로젝트부터 (공백으로 구분) 분당 실제 소비는 B를 분의 시작을 나타낸다 분
늦게 벨 끝. 시작 시간에 따라 운동 프로그램 오름차순으로는 두 프로젝트는 시간이 충돌되지 않습니다, 주어진
상황.
산출
- 이 프로젝트는, 출력 "수락"의 첫 번째 줄, 오늘의 출력의 두 번째 행 가능한 경우, 출력은 두 줄을 포함
"런타임 오류"출력, 그렇지 않으면 첫 번째 줄, 처음 몇 분 동안 출력의 두 번째 줄, 마지막으로 실제 남은 후
종 피곤 죽은.
샘플 입력
농구 1 10 1
샘플 출력
허용
1,140
해결 방법 :
- 시뮬레이션 ...
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;
int n, m;
int a[2005];
int main()
{
cin >> n >> m;
for(int i = 1; i <= m; i++)
{
string t; cin >> t;
int u, v, w;
cin >> u >> v >> w;
for(int j = u; j <= v; j++) a[j] += w;
}
for(int i = 1; i <= 1440; i++)
{
n++, n -= a[i];
if(n <= 0) {cout << "Runtime Error\n" << i; return 0;}
}
cout << "Accepted\n" << n;
return 0;
}
월드 오브 워크 래프트
기술
- 와우 작은 x는 엑스터시입니다
그가 죽음의 기사를 구울의 제어 및 N 사냥 갈 (번호 1 ~ N)에 있었다
구울하는 HP를 보완 할 수있는 마법, "죽음의 소용돌이"라고했다 죽음의 기사를
싸우는 적의 과정 공격 할 구울은 구울 HP는 줄일 수
, 항상 자신의 힘의 상황, HP의 멀티 구울 얼마나 많은 HP의 즉 K-값을 알고 싶은 작은 X를
주문 캐스팅하는 방법을 결정하기 위해
그를 도와 줄 사람을 물어 )
는 입력 데이터의 공연장 밑줄 :(로 전송 된 신호)의 작은 X 삼가지
A_i_a는 i 번째 구울 전송 적의 공격을 나타내고, i 번째 구울이 점 손실
되면 HP 그것은 (언데드가 죽어) HP가 <= 0, 다음 구울 사망입니다.
원수는 죽은 구울을 공격하지 않습니다.
C_i_a은 죽음의 기사는 i 번째 구울에 죽음의 나선을 발표 나타내며,이 점 HP를 추가합니다.
HP는 상한 값입니다.
죽음의 기사 죽음의 고리는 죽은 구울에 발행되지 않습니다
당신이 작은 X에 쿼리를 실행 표현한다 Q_k
입력
- 첫 번째 라인은 양의 정수, N
, N, N의 정수를 나타내는 후 초기 구울는 HP의
값은 양의 정수 m에이다
에 출사 X m 행당 덜 신호선
산출
- 각 문의 작은 X를 들어, K-HP 멀티 구울 출력 얼마나 HP, 구울 경우, 총
K의 부족 출력 -1. 각 행의 수입니다.
출력 숫자의 마지막 라인 : 구울 잔존 후 전투 숫자
샘플 입력
5
1 2 3
4 5
(10)
Q 2
4 (6)
C 1-4
Q 2
2부터 1
3 3
1 (3)
Q 4
C 2~10
Q 1
샘플 출력
4
5
-1
(11)
삼
해결 방법 :
- 맨 손으로 나무의 문제를 균형. 나는 FHQ-treap로 알고 있습니다.
- 각각의 수정 방법은 개정 전 지점에 점을 삭제 한 후 수정 된 점을 추가하는 것입니다.
#include <iostream>
#include <cstdio>
#include <cstdlib>
#define N 30005
using namespace std;
struct T {int l, r, val, dat, size;} t[N * 4];
int n, m, root, x, y, z, tot, now;
int a[N];
int read()
{
int x = 0; char c = getchar();
while(c < '0' || c > '9') c = getchar();
while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
return x;
}
int New(int val)
{
t[++tot].val = val;
t[tot].dat = rand();
t[tot].size = 1;
return tot;
}
void up(int p) {t[p].size = t[t[p].l].size + t[t[p].r].size + 1;}
void split(int p, int val, int &x, int &y)
{
if(!p) {x = y = 0; return;}
if(t[p].val <= val) x = p, split(t[p].r, val, t[p].r, y);
else y = p, split(t[p].l, val, x, t[p].l);
up(p);
}
int merge(int x, int y)
{
if(!x || !y) return x + y;
if(t[x].dat > t[y].dat)
{
t[x].r = merge(t[x].r, y);
up(x); return x;
}
else
{
t[y].l = merge(x, t[y].l);
up(y); return y;
}
}
void insert(int val)
{
split(root, val - 1, x, y);
root = merge(merge(x, New(val)), y);
}
void erase(int val)
{
split(root, val, x, z);
split(x, val - 1, x, y);
y = merge(t[y].l, t[y].r);
root = merge(merge(x, y), z);
}
int valOfRank(int rank)
{
int p = root;
while(p)
{
if(t[t[p].l].size + 1 == rank) break;
else if(t[t[p].l].size >= rank) p = t[p].l;
else rank -= t[t[p].l].size + 1, p = t[p].r;
}
return t[p].val;
}
int main()
{
cin >> n, now = n;
for(int i = 1; i <= n; i++)
{
a[i] = read();
insert(a[i]);
}
cin >> m;
for(int i = 1; i <= m; i++)
{
char c[3]; scanf("%s", c);
if(c[0] == 'A')
{
int pos = read(), val = read();
erase(a[pos]);
a[pos] -= val;
if(a[pos] <= 0) now--;
else insert(a[pos]);
}
else if(c[0] == 'C')
{
int pos = read(), val = read();
erase(a[pos]);
a[pos] += val;
insert(a[pos]);
}
else if(c[0] == 'Q')
{
int rank = read();
if(now < rank) printf("-1\n");
else printf("%d\n", valOfRank(now - rank + 1));
}
}
cout << now;
return 0;
}
디아블로
기술
- 재생 디아블로 I 지루 작은 X ...
N 마법으로 게임의 주인공이
각각 마법 여러 단계로 나누어, 마법 [I]를 수치 (0 제외), i 번째 P 갖는다
마법 당 각각을 레벨 I는 단계 마법 효과의 J가 영향 값을 갖는다
(W)를 [I]는 [j]가 마법 1 리터 각 마법 필요
이상 마법 금 필요 i 번째 마법 마법 C [I]의 가격
(수정없이 소년) 만 작은 X의 m 금화는
당신의 작업은 작은 x는 모든 마법의 가치와 대부분의 마법 효과를 확인하기 위해 책을 구입하는 방법을 결정하는 데 도움이하는 것입니다
큰
모든 마법의 시작 부분에 0을 효과는 0
입력
- 나노 개의 공간 분리 된 정수의 첫번째 행
매직 설명 N N 행
I + 1-i 행의 형식은 다음과 마법에서 설명
C [I], P [I] w는 [I] [1] w [i]를 [2] ... w [i]는 [P [I]
산출
- 정수의 제 1 출력 라인의 최대 효과, 즉 값.
행 n 개의 출력 프로그램 후 :
나는 + 1 개 번째 라인 [I]는 의미 정수 V가 i 번째는 매직 V [i]는 단계 내용을 결정하는
여러 솔루션의 출력들은 그룹의 최소 보낼 경우
경우 더 솔루션보다 출력의 그룹 중 어느
샘플 입력
3 10
1 3 1 2 2
2 3 2 4 6
3 3 2 1 10
샘플 출력
(11)
1
0
삼
해결 방법 :
- 선형 DP.
- DP (I, J)를 설정하는 마법 난 효과를 얻을 금의 최대 값 J 전에 처리된다.
- 하나 - 항목의 상태 (I 1),이 최적 값을 고려 하였다는 문서의 다른 형태를 취.
- 상대적으로 쉬운, 주로 프로그램을 내보낼 수 있습니다.
- I는 (I, J)를 사용하여 생각 동기 DP (I, J)를 수득하는 경우와 문서를 오퍼레이터가 (I, J)를 기록하는 DP의 시간.
- 좋아, 얻을.
#include <iostream>
#include <cstdio>
#include <algorithm>
#define N 2005
using namespace std;
struct Ans {int id, lev;} ans[N];
struct A {int val, id, lev;} a[N][N];
int n, T;
int cnt[N];
int w[N][N], v[N][N], dp[N][N];
bool cmp(Ans x, Ans y) {return x.id < y.id;}
int main()
{
cin >> n >> T;
for(int i = 1; i <= n; i++)
{
int c; cin >> c;
int p; cin >> p;
cnt[i] = p;
for(int j = 1; j <= p; j++)
cin >> v[i][j], w[i][j] = c * j;
}
for(int i = 1; i <= n; i++)
for(int j = 0; j <= T; j++)
for(int k = 0; k <= cnt[i]; k++)
if(j - w[i][k] >= 0)
if(dp[i - 1][j - w[i][k]] + v[i][k] > dp[i][j])
{
dp[i][j] = dp[i - 1][j - w[i][k]] + v[i][k];
a[i][j].id = i, a[i][j].lev = k;
a[i][j].val = w[i][k];
}
else if(dp[i - 1][j - w[i][k]] + v[i][k] == dp[i][j] && w[i][k] < a[i][j].val)
{
dp[i][j] = dp[i - 1][j - w[i][k]] + v[i][k];
a[i][j].id = i, a[i][j].lev = k;
a[i][j].val = w[i][k];
}
cout << dp[n][T] << endl;
int now = T;
for(int i = n; i >= 1; i--)
{
ans[i].id = a[i][now].id;
ans[i].lev = a[i][now].lev;
now = now - a[i][now].val;
}
sort(ans + 1, ans + 1 + n, cmp);
for(int i = 1; i <= n; i++) cout << ans[i].lev << endl;
return 0;
}