版权声明:Fashion Education https://blog.csdn.net/ModestCoder_/article/details/83756567
@飞旭杯-迎接NOIP2018
刷一场普及难度的比赛心情好~~
我是不会告诉你这场比赛是我同学出的
T1:帅哥(Handsome)
签到题,
样例可自行画图理解。
发现:
1、瑶瑶首先要走到帅哥行走的那条直线上
2、向前走一步,再向后走一步等于没走
这样题目就变得很水了
Code:
//对于每个帅哥,先让瑶瑶走到帅哥行走的那条线上,算出之后两人的距离,
//这个距离必须为正偶数
var
i, n, x, y, x1, y1, ans, s : longint;
d, kongge : char;
begin
readln(n, x, y);
for i := 1 to n do
begin
readln(x1, y1, kongge, d);
if d = 'U' then
begin
s := (x1 - x) - abs(y1 - y);
if (s >= 0) and (s and 1 = 0) then inc(ans);
end else
if d = 'L' then
begin
s := (y1 - y) - abs(x1 - x);
if (s >= 0) and (s and 1 = 0) then inc(ans);
end else
if d = 'R' then
begin
s := (y - y1) - abs(x - x1);
if (s >= 0) and (s and 1 = 0) then inc(ans);
end else
if d = 'D' then
begin
s := (x - x1) - abs(y - y1);
if (s >= 0) and (s and 1 = 0) then inc(ans);
end;
end;
writeln(ans);
end.
T2:旭数(Xu)
数据范围很小,1000000内质数很少
筛出1000000内所有质数,
旭数=18 * 质数+36 * 质数,所以只要O(质数个数^2)枚举就行了
最后搞个前缀和
筛法用普通筛都能过,线筛的话更快一点
Code:
const
maxn = 1000000;
var
flag, xu : array[0..maxn] of boolean;
sum, prime : array[0..maxn] of longint;
n, l, r, i, j, tot : longint;
begin
for i := 2 to maxn do
begin
if not flag[i] then
begin
inc(tot);
prime[tot] := i;
end;
for j := 1 to tot do
begin
if i * prime[j] > maxn then break;
flag[i * prime[j]] := true;
if i mod prime[j] = 0 then break;
end;
end;
for i := 1 to tot do
for j := 1 to tot do
begin
if 18 * prime[i] + 36 * prime[j] > maxn then break;
xu[18 * prime[i] + 36 * prime[j]] := true;
end;
for i := 1 to maxn do sum[i] := sum[i - 1] + ord(xu[i]);
readln(n);
for i := 1 to n do
begin
readln(l, r);
writeln(sum[r] - sum[l - 1]);
end;
end.
T3:得分(Score)
看完题目,马上想到:数据结构?
然后又想到:支持单点修改,查询第k大?
想到了:树状数组!
裸题啊!赤果果的树状数组
不详细介绍了吧,看代码秒懂啊
经主办同学要求,我需要帮他码码T3的c++标程(他不会c++,而且他用的方法是堆),我就在比赛前破例用一次c++(告别pascal还剩6天祭)
Code:
#include <bits/stdc++.h>
#define res register int
#define maxn 3000005
#define inf 2146483647
#define ll long long
using namespace std;
int s[maxn][4], tree[maxn], n, m, a, b, c, k;
inline int read(){
int s = 0, w = 1;
char c = getchar();
while (c < '0' || c > '9'){
if (c == '-') w = -1; c = getchar();
}
while (c >= '0' && c <= '9') s = (s << 3) + (s << 1) + (c ^ 48), c = getchar();
return s * w;
}
inline void add(int x, int y){for (; x <= maxn; x += (x & -x)) tree[x] += y;}
inline int query(int x){int s = 0; for (; x > 0; x -= (x & -x)) s += tree[x]; return s;}
inline int find(int x){
int s = 0;
for (int l = 0, r = maxn; l <= r;){
int mid = (l + r) >> 1;
if (query(mid) >= x) r = mid - 1, s = mid; else l = mid + 1;
}
return s;
}
int main(){
n = read(), m = read(), a = read(), b = read(), c = read(), k = read();
for (res i = 1; i <= n; ++ i){
s[i][1] = read(), s[i][2] = read(), s[i][3] = read();
add(s[i][1] * a + s[i][2] * b + s[i][3] * c, 1);
}
for (res i = 1; i <= m; ++ i){
int x = read();
if (x == 0){
printf("%d\n", find(n + 1 - k));
} else{
int x = read(), y = read(), z = read();
add(s[x][1] * a + s[x][2] * b + s[x][3] * c, -1);
s[x][y] = z;
add(s[x][1] * a + s[x][2] * b + s[x][3] * c, 1);
}
}
return 0;
}
T4:校牌(Card)
加强版的小背包问题,我是真的不会啊
本来,是有30分dfs暴搜子任务+30分暴力dp子任务,我就这样拿了60
Code:
uses math;
var
dp : array[0..32,0..10000000] of longint;
m, w : array[0..10000] of longint;
n, k, s, sum, i, j, l, ans : longint;
procedure dfs(t, sum, q, tot : longint);
begin
if t > n then
begin
ans := max(ans, sum); exit;
end;
dfs(t + 1, sum, q, tot);
if (q + m[t] <= s) and (tot < k) then dfs(t + 1, sum + w[t], q + m[t], tot + 1);
end;
procedure do1;
begin
dfs(1, 0, 0, 0);
writeln(ans);
halt;
end;
begin
readln(n, k, s);
for i := 1 to n do
begin
readln(m[i], w[i]);
inc(sum, m[i]);
end;
if n <= 25 then do1;
s := min(s, sum);
for i := 1 to n do
begin
for j := k downto 1 do
for l := s downto m[i] do
dp[j][l] := max(dp[j][l], dp[j - 1][l - m[i]] + w[i]);
end;
writeln(dp[k][s]);
end.
后来,因为有同学用折半搜索水过了@fxkkks,经hsy奆佬要求加强了数据
此题正解:模拟退火(hsy出的题目hsy自己过了),我当然是不会的啦