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

## A. Drink (Hdu 6743)

### 解题思路

#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;
cin >> n >> m;
int ans = 1e9 + 7;
for (int x, y, i = 1; i <= n; ++i)
{
cin >> x >> y;
ans = min(ans, (int)ceil(m * 1.0 / x) * y);
}
cout << ans << endl;
}
return 0;
}


## B. GPA (Hdu 6744)

### 解题思路

$11^4$种情况爆搜就好了。

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

double ans;

double ch(int x){
if (x >= 95) return(4.3);
if (x >= 90) return(4.0);
if (x >= 85) return(3.7);
if (x >= 80) return(3.3);
if (x >= 75) return(3.0);
if (x >= 70) return(2.7);
if (x >= 67) return(2.3);
if (x >= 65) return(2.0);
if (x >= 62) return(1.7);
if (x >= 60) return(1.0);
return 0;
}

void solve(int x,int pos,double mark){
if (pos==4){
mark += ch(x);
ans = max(ans, mark);
return;
}
if (x >= 95) solve(x-95,pos+1,mark+4.3);
if (x >= 90) solve(x-90,pos+1,mark+4.0);
if (x >= 85) solve(x-85,pos+1,mark+3.7);
if (x >= 80) solve(x-80,pos+1,mark+3.3);
if (x >= 75) solve(x-75,pos+1,mark+3.0);
if (x >= 70) solve(x-70,pos+1,mark+2.7);
if (x >= 67) solve(x-67,pos+1,mark+2.3);
if (x >= 65) solve(x-65,pos+1,mark+2.0);
if (x >= 62) solve(x-62,pos+1,mark+1.7);
if (x >= 60) solve(x-60,pos+1,mark+1.0);
solve(x,pos+1,mark);
}

int main(void) {
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int kase; cin>>kase;
for (int ii=1,m; ii <= kase; ii++) {
cin>>m;
ans = 0;
solve(m,1,0);
cout<<fixed<<setprecision(1)<<ans<<endl;
}
return 0;
}


## C. Dec (Hdu 6745)

### 解题思路

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

int dp[1002][1002];

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)
{
dp[1][1] = 1;
for (int i = 1; i <= 1000; ++i)
for (int j = 1; j <= 1000; ++j)
{
if ((i == 1) && (j == 1))
continue;
if (i == 1)
dp[i][j] = dp[i][j - 1] + (__gcd(i, j) == 1);
else if (j == 1)
dp[i][j] = dp[i - 1][j] + (__gcd(i, j) == 1);
else
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]) + (__gcd(i, j) == 1);
}
int kase;
cin >> kase;
for (int a, b, ii = 1; ii <= kase; ii++)
{
write(dp[a][b], '\n');
}
return 0;
}


## D. Civilization (Hdu 6746)

### 解题思路

#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 dis(int i, int j, int x, int y)
{
int qwq = abs(i - x) + abs(j - y);
return (int)ceil(qwq * 1.0 / 2);
}

int a[505][505];

int n;

int dx[24] = {0, -1, 0, 1, -2, -1, 0, 1, 2, -3, -2, -1, 1, 2, 3, -2, -1, 0, 1, 2, -1, 0, 1, 0};

int dy[24] = {3, 2, 2, 2, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, -1, -1, -1, -1, -1, -2, -2, -2, -3};

int up[9] = {0, 1 * 1 * 8, 2 * 2 * 8, 3 * 3 * 8, 4 * 4 * 8, 5 * 5 * 8, 6 * 6 * 8, 7 * 7 * 8, 8 * 8 * 8};

int solve(int x, int y)
{
vector<int> qwq;
for (int i = 0; i < 24; ++i)
{
if ((x + dx[i] <= 0) || (x + dx[i] > n) || (y + dy[i] <= 0) || (y + dy[i] > n))
continue;
qwq.push_back(a[x + dx[i]][y + dy[i]]);
}
sort(qwq.begin(), qwq.end(), greater<int>());
int cur = a[x][y];
int people = 1;
int ju = 0;
size_t len = 0;
int tot = 0;
int gg = 0;
while (people < 9)
{
gg = (int)ceil((up[people] - tot) * 1.0 / cur);
ju += gg;
tot += gg * cur;
people++;
if (len < qwq.size())
{
cur += qwq[len];
++len;
}
}
return ju;
}

int main(void)
{
int kase;
for (int x, y, ii = 1; ii <= kase; ii++)
{
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= n; ++j)
int ans = 1e9 + 7;
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= n; ++j)
{
ans = min(ans, dis(i, j, x, y) + solve(i, j));
}
}
printf("%d\n", ans);
}
return 0;
}


## E. Rotate (Hdu 6747)

### 题目大意

$a[i]$不降。

### 解题思路

$E(\text{点数}) = \sum\limits_{i = 1}^{n} \dfrac{a[i]}{2}$

$\frac{ \frac{2\pi}{a[i+1]} + \frac{2\pi}{a[i]}}{2\pi} = \frac{1}{a[i+1]} + \frac{1}{a[i]}$

$\left( \dfrac{1}{a[i+1]} + \dfrac{1}{a[i]} \right) \dfrac{a[i]}{2} \dfrac{a[i+1]}{2} = \dfrac{a[i] + a[i+1]}{4}$

$E(\text{边数})$$E(\text{点数})$代入化简得

$E(\text{联通块}) = \dfrac{a[1] + a[n]}{4}$

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

LL mo = 1e9 + 7;

int main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int inv4 = 250000002;
int kase;
cin >> kase;
for (int ii = 1; ii <= kase; ii++)
{
int n;
cin >> n;
int a;
cin >> a;
if (n == 1)
{
cout << a / 2 << endl;
continue;
}
else
{
int b;
for (int i = 2; i <= n; ++i)
cin >> b;
cout << (LL)(a + b) * inv4 % mo << endl;
}
}
return 0;
}


## F. Matrix (Hdu 6748)

### 解题思路

qwq

qwq


## G. Mosquito (Hdu 6749)

### 解题思路

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

#define MIN(a, b) (((a) < (b) ? (a) : (b)))
#define MAX(a, b) (((a) > (b) ? (a) : (b)))

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 M 100
#define N 640

const int INF = 233333333;
struct data
{
int to, nxt, flow;
} line[N * 2];
int n, m, l, r, ans, team[M * 2], dis[M * 2], head[M * 2], num, u, v, st, en, qaq;

void add(int u, int v, int w)
{
num++;
line[num].to = v;
line[num].flow = w;
num++;
line[num].to = u;
line[num].flow = 0;
}
bool BFS()
{
int u, v;
l = r = 0;
team[++r] = st;
memset(dis, 0, sizeof(dis));
dis[st] = 1;
while (l < r)
{
u = team[++l];
for (int i = head[u]; i; i = line[i].nxt)
{
v = line[i].to;
if (dis[v] == 0 && line[i].flow)
{
dis[v] = dis[u] + 1;
team[++r] = v;
}
}
}
if (dis[en])
return true;
else
return false;
}
int DFS(int u, int f)
{
if (u == en)
return f;
int tmp = 0;
int qwq = 0;
int v = 0;
for (int i = head[u]; i; i = line[i].nxt)
{
v = line[i].to;
if (dis[v] == dis[u] + 1 && line[i].flow)
{
qwq = DFS(v, MIN(f - tmp, line[i].flow));
line[i].flow -= qwq;
line[i ^ 1].flow += qwq;
tmp += qwq;
if (tmp == f)
return tmp;
}
}
return tmp;
}

int x[8], y[8], cnt[8];

int k;

int ddis[1001][1001][8];

int main(void)
{
int t;
while (t--)
{
long long qmq = 0;
for (int i = 1; i <= k; ++i)
{
qmq += (long long)cnt[i];
for (int a = 1; a <= n; ++a)
for (int b = 1; b <= m; ++b)
{
ddis[a][b][i] = abs(a - x[i]) + abs(b - y[i]);
}
}
if (qmq < (long long)n * m)
{
printf("-1\n");
continue;
}
int tot = (1 << (k));
st = 0;
en = tot + k + 1;
int l = 0, r = n + m;
int cc[66] = {0};
while (l < r)
{
int mid = (l + r) >> 1;
num = 1;
for (int i = st; i <= en; ++i)
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
int sign = 0;
for (int a = 1; a <= k; ++a)
{
if (ddis[i][j][a] <= mid)
sign |= (1 << (a - 1));
}
cc[sign]++;
}
}
for (int i = 0; i < (1 << k); ++i)
{
for (int a = 1; a <= k; ++a)
if ((i >> (a - 1)) & 1)
add(i + 1, tot + a, INF);
cc[i] = 0;
}
for (int i = 1; i <= k; ++i)
int dd = 0;
while (BFS())
dd += DFS(st, INF);
if (dd < n * m)
l = mid + 1;
else
r = mid;
}
write(r, '\n');
}
return 0;
}


## H. Function (Hdu 6750)

### 解题思路

$[gcd(t,\dfrac{i}{t}) = 1] = \epsilon(gcd(t,\dfrac{i}{t})) = \sum\limits_{d|gcd(t,\frac{i}{t})} \mu(d) 1(\frac{gcd(t,\frac{i}{t})}{d}) = \sum\limits_{d|gcd(t,\frac{i}{t})} \mu(d)$出发。

\begin{aligned} \sum\limits_{i = 1}^{n} \sum\limits_{t|i} t [gcd(t,\dfrac{i}{t}) = 1] &= \sum\limits_{i = 1}^{n} \sum\limits_{t|i} t \sum\limits_{d|gcd(t,\frac{i}{t})} \mu(d) \\ &= \sum\limits_{i = 1}^{n} \sum\limits_{t|i} t \sum\limits_{d|t,d|\frac{i}{t}} \mu(d) \\ 调整顺序，枚举\mu(d)考虑有多少个&= \sum\limits_{d = 1}^{n} \mu(d) \sum\limits_{t = 1}^{\lfloor \frac{n}{d} \rfloor} td \lfloor \frac{n}{d^2 t} \rfloor \\ (调整顺序，将最右边的d^2t看成关于\lfloor \frac{n}{d^2 t} \rfloor的自变量)&= \sum\limits_{t = 1}^{n} \lfloor \frac{n}{t} \rfloor \sum\limits_{d^2|t} \mu(d) \frac{t}{d} \\ 调整顺序&= \sum\limits_{d = 1}^{\sqrt{n}} \mu(d) \sum\limits_{t = 1}^{\lfloor \frac{n}{d^2} \rfloor} \lfloor \frac{n}{d^2t} \rfloor \frac{td^2}{d} \\ &= \sum\limits_{d = 1}^{\sqrt{n}} \mu(d)d \sum\limits_{t = 1}^{\lfloor \frac{n}{d^2} \rfloor} t \lfloor \frac{n}{d^2t} \rfloor \\ G(x) = \sum\limits_{i = 1}^{x} t \lfloor \frac{i}{t} \rfloor \to &=\sum\limits_{d = 1}^{\sqrt{n}} \mu(d)d \cdot G \left( \lfloor \frac{n}{d^2} \rfloor \right) \end{aligned}

$G(x)$可用整数分块求，求累加和也可用整数分块求。

#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 LL mo = 1e9 + 7;

const LL N = 1e6 + 8;

bool visit[N];

LL prim[N];

int u[N];

LL sum_mu[N];

void pre_mu()
{
sum_mu[0] = 0;
memset(visit, false, sizeof(visit));
int tot = 0;
u[1] = 1;
sum_mu[1] = 1;
for (int i = 2; i <= N; i++)
{
if (!visit[i])
{
visit[i] = true;
prim[++tot] = i;
u[i] = -1;
}
for (int j = 1; j <= tot; j++)
{
if (prim[j] * i > N)
break;
visit[prim[j] * i] = true;
if (i % prim[j])
u[prim[j] * i] = -u[i];
else
{
u[prim[j] * i] = 0;
break;
}
}
sum_mu[i] = (sum_mu[i - 1] + (LL)u[i] * i % mo + mo) % mo;
}
}

LL inv2 = 500000004;

LL calc(LL l, LL r)
{
LL nxt = 0;
LL tmp = 0;
while (l <= r)
{
nxt = r / (r / l);
tmp = (tmp + (r / l) * ((l + nxt) % mo) % mo * ((nxt - l + 1) % mo) % mo * inv2 % mo) % mo;
l = nxt + 1;
}
return tmp;
}

int main(void)
{
pre_mu();
int kase;
for (int ii = 1; ii <= kase; ii++)
{
LL n;
LL ans = 0;
LL up = sqrt(n);
LL l = 1;
LL nxt = 0;
while (l <= up)
{
nxt = (LL)sqrt(n / (n / (l * l)));
if (nxt > up)
nxt = up;
ans = (ans + calc(1, n / (l * l)) * ((sum_mu[nxt] - sum_mu[l - 1] + mo) % mo) % mo) % mo;
l = nxt + 1;
}
write(ans, '\n');
}
return 0;
}


posted @ 2020-07-22 13:26  ~Lanly~  阅读(209)  评论(3编辑  收藏