# 2020百度之星程序设计大赛初赛二

## A. Poker (Hdu 6775)

### 解题思路

$k \geq \dfrac{m - a}{(m - \lfloor m \times (1 - p \%) \rfloor)}$

(代码是考虑小于号的情况)

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

int main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int t;
cin >> t;
while (t--)
{
int n, m, p;
cin >> n >> m >> p;
if (n < m)
{
cout << 0 << endl;
continue;
}
int qwq = m - m * (100 - p) / 100;
int cnt = n / qwq;
n %= qwq;
cnt -= (m - n) / qwq;
if ((m - n) % qwq == 0)
++cnt;
cout << cnt << endl;
}
return 0;
}


## B. Distance (Hdu 6776)

### 解题思路

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;

int main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int kase;
cin >> kase;
for (int ii = 1; ii <= kase; ii++)
{
int n;
cin >> n;
vector<LL> qwq(n);
for (int i = 0; i < n; ++i)
cin >> qwq[i];
sort(qwq.begin(), qwq.end());
LL ans = 0;
for (int i = 0; i < n - 1; ++i)
{
ans += (qwq[i + 1] - qwq[i]) * (LL)(i + 1) * (LL)(n - i - 1);
}
cout << ans << endl;
}
return 0;
}


## C. Covid (Hdu 6777)

### 题目大意

$n$个人，告诉你每个人每刻的位置。如果有人和感染病毒的人在某一刻在同一位置，那么那人也被感染。初始只有1号人感染了，问最终感染人的编号。

### 解题思路

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <typename T>
{
int s = 0, c = getchar();
x = 0;
while (isspace(c))
c = getchar();
if (c == 45)
s = 1, c = getchar();
while (isdigit(c))
x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s)
x = -x;
}

template <typename T>
void write(T x, char c = ' ')
{
int b[40], l = 0;
if (x < 0)
putchar(45), x = -x;
while (x > 0)
b[l++] = x % 10, x /= 10;
if (!l)
putchar(48);
while (l)
putchar(b[--l] | 48);
putchar(c);
}

int main(void)
{
int kase;
for (int ii = 1; ii <= kase; ii++)
{
int n;
cin >> n;
int tot = 0;
vector<queue<pair<int, int>>> people(n);
for (int len, t, p, i = 0; i < n; ++i)
{
cin >> len;
for (int j = 1; j <= len; ++j)
{
cin >> t >> p;
people[i].push(make_pair(t, p));
tot = max(t, tot);
}
}
vector<bool> sign(n, 0);
sign[0] = true;
int pos[12] = {0};
for (int i = 1; i <= tot; ++i)
{
for (int j = 0; j < n; ++j)
{
if (sign[j] && (!people[j].empty()) && people[j].front().first == i)
{
pos[people[j].front().second] = i;
}
}
for (int j = 0; j < n; ++j)
{
if ((!people[j].empty()) && people[j].front().first == i)
{
if (pos[people[j].front().second] == i)
sign[j] = true;
people[j].pop();
}
}
}
printf("1");
for (int i = 2; i <= n; ++i)
if (sign[i - 1])
printf(" %d", i);
puts("");
}
return 0;
}


## D. Car (Hdu 6778)

### 解题思路

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <typename T>
{
int s = 0, c = getchar();
x = 0;
while (isspace(c))
c = getchar();
if (c == 45)
s = 1, c = getchar();
while (isdigit(c))
x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s)
x = -x;
}

template <typename T>
void write(T x, char c = ' ')
{
int b[40], l = 0;
if (x < 0)
putchar(45), x = -x;
while (x > 0)
b[l++] = x % 10, x /= 10;
if (!l)
putchar(48);
while (l)
putchar(b[--l] | 48);
putchar(c);
}

void DFS(int tot, int cnt[], int sum[], int &ans, int n)
{
if (tot == 10)
{
int qwq = 1e9;
for (int i = 0; i < 5; ++i)
{
qwq = min(qwq, sum[i]);
}
ans = min(ans, n - qwq);
return;
}
for (int i = 0; i < 5; ++i)
{
sum[i] += cnt[tot];
DFS(tot + 1, cnt, sum, ans, n);
sum[i] -= cnt[tot];
}
}

int main(void)
{
int kase;
for (int ii = 1; ii <= kase; ii++)
{
int n;
int cnt[10] = {0};
for (int x, i = 1; i <= n; ++i)
{
cnt[x % 10]++;
}
int ans = 1e9 + 7;
int sum[5] = {0};
DFS(0, cnt, sum, ans, n);
write(ans, '\n');
}
return 0;
}


## E. Drink (Hdu 6779)

### 题目大意

$n$个人，告诉你他们对于可乐、雪碧、芬达的喜好程度的排序。现在你有可乐、雪碧、芬达$a,b,c(a+b+c=n)$瓶，问如何分配，使得他们的快乐值最大。若一个人喝到第一喜欢的，有3快乐值；第二喜欢的，有2快乐值；第三喜欢的，有1快乐值。

### 解题思路

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <typename T>
{
int s = 0, c = getchar();
x = 0;
while (isspace(c))
c = getchar();
if (c == 45)
s = 1, c = getchar();
while (isdigit(c))
x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s)
x = -x;
}

template <typename T>
void write(T x, char c = ' ')
{
int b[40], l = 0;
if (x < 0)
putchar(45), x = -x;
while (x > 0)
b[l++] = x % 10, x /= 10;
if (!l)
putchar(48);
while (l)
putchar(b[--l] | 48);
putchar(c);
}

#define MIN(a, b) (((a) < (b) ? (a) : (b)))
#define MAX(a, b) (((a) > (b) ? (a) : (b)))
#define fo(i, a, b) for (int i = (a); i <= (b); ++i)

#define M 30
#define N 12

const int INF = 23333333;
int head[N], nxt[M * 2], to[M * 2], flow[M * 2], cost[M * 2], pre[N], dis[N], team[N * 5], val[N], fr[M * 2];
int num, u, v, w, st, en;
bool vis[N];
LL ans;

void add(int u, int v, int f, int w)
{
num++;
to[num] = v;
fr[num] = u;
flow[num] = f;
cost[num] = w;
num++;
to[num] = u;
fr[num] = v;
flow[num] = 0;
cost[num] = -w;
}
inline bool SPFA()
{
int l = 0, r = 1;
team[1] = st;
fo(i, st, en)
{
dis[i] = INF;
pre[i] = 0;
vis[i] = false;
}
dis[st] = 0;
vis[st] = 1;
while (l < r)
{
u = team[++l];
for (int i = head[u]; i; i = nxt[i])
{
v = to[i];
if (flow[i] && dis[v] > dis[u] + cost[i])
{
dis[v] = dis[u] + cost[i];
pre[v] = i;
if (!vis[v])
{
team[++r] = v;
vis[v] = 1;
}
}
}
vis[u] = 0;
}
if (pre[en])
return true;
else
return false;
}
inline void DFS()
{
int qwq = INF;
for (int i = pre[en]; i; i = pre[fr[i]])
qwq = MIN(qwq, flow[i]);
ans += (LL)qwq * (LL)dis[en];
for (int i = pre[en]; i; i = pre[fr[i]])
{
flow[i] -= qwq;
flow[i ^ 1] += qwq;
}
}

int main(void)
{
int kase;
for (int ii = 1; ii <= kase; ii++)
{
num = 1;
ans = 0;
int n, a, b, c;
st = 0;
en = 10;
char qwq[4];
int cnt[6] = {0};
for (int i = 1; i <= n; ++i)
{
scanf("%s", qwq);
if (strcmp(qwq, "012") == 0)
cnt[0]++;
if (strcmp(qwq, "021") == 0)
cnt[1]++;
if (strcmp(qwq, "102") == 0)
cnt[2]++;
if (strcmp(qwq, "120") == 0)
cnt[3]++;
if (strcmp(qwq, "201") == 0)
cnt[4]++;
if (strcmp(qwq, "210") == 0)
cnt[5]++;
}

while (SPFA())
DFS();
write(-ans, '\n');
for (int i = st; i <= en; ++i)
}
return 0;
}


## F. Cloth (Hdu 6780)

### 解题思路

qwq

qwq


## G. Solo (Hdu 6781)

### 题目大意

$n$题，已知自己和对手完成每道题的时间，且对手从第1题开始写。问如何安排顺序，使得获得的分数最大。

### 解题思路

$dp[i][j]$表示前$i$题，得分为$j$时的最大超前对手时间。

$dp[i+1][j+1] = \max(dp[i+1][j+1],dp[i][j]-(a[i+1]-b[i+1]))\ \ if\ \ \ dp[i][j]-(a[i+1]-b[i+1])\geq 0$

$dp[i+1][j] = \max(dp[i+1][j],dp[i][j] + b[i+1])$

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
template <typename T>
{
int s = 0, c = getchar();
x = 0;
while (isspace(c))
c = getchar();
if (c == 45)
s = 1, c = getchar();
while (isdigit(c))
x = (x << 3) + (x << 1) + (c ^ 48), c = getchar();
if (s)
x = -x;
}

template <typename T>
void write(T x, char c = ' ')
{
int b[40], l = 0;
if (x < 0)
putchar(45), x = -x;
while (x > 0)
b[l++] = x % 10, x /= 10;
if (!l)
putchar(48);
while (l)
putchar(b[--l] | 48);
putchar(c);
}

const int N = 2e3 + 8;

LL dp[N][N];

LL a[N], b[N];

int main(void)
{
int kase;
for (int ii = 1; ii <= kase; ii++)
{
int n;
for (int i = 0; i <= n; ++i)
for (int j = 0; j <= n; ++j)
dp[i][j] = -1;
for (int i = 1; i <= n; ++i)
{
}
for (int i = 1; i <= n; ++i)
{
}
dp[0][0] = 0;
for (int i = 1; i <= n; ++i)
for (int j = 0; j <= n; ++j)
{
if (dp[i - 1][j] != -1)
{
if (dp[i - 1][j] + b[i] >= a[i])
dp[i][j + 1] = max(dp[i][j + 1], dp[i - 1][j] - (a[i] - b[i]));
dp[i][j] = max(dp[i][j], dp[i - 1][j] + b[i]);
}
}
int ans = 0;
for (int i = 0; i <= n; ++i)
if (dp[n][i] != -1)
ans = i;
write(ans, '\n');
}
return 0;
}


## H. Hanoi (Hdu 6782)

qwq

### 解题思路

qwq

qwq


posted @ 2020-07-25 17:48  ~Lanly~  阅读(409)  评论(0编辑  收藏