三校聯考-水題狂歡信心賽
T1
當 \(k = 1\) 時,如果要查詢的數為質數直接輸出 \(2\),如果不是質數,輸出它除 \(1\) 外最小的因子。
當 \(k = 2\) 時,輸出 \(\lfloor \frac x 2 \rfloor + 1\)。
如果 \(y \geq \lfloor \frac x 2 \rfloor + 1\),那麼 \(x \bmod y = x - y\),當 \(y = \lfloor \frac x 2 \rfloor + 1\) 一定最優。
如果 \(y \leq \lfloor \frac x 2 \rfloor\)
-
當 \(x\) 是偶數時。
若 \(y = \lfloor \frac x 2 \rfloor\)
若 \(y < \lfloor \frac x 2 \rfloor\),那麼 \(x \bmod y < y\),所以 \(x \bmod y < \lfloor \frac x 2 \rfloor - 1 = \lceil \frac x 2 \rceil - 1 = x \bmod y\)。 -
當 \(x\) 是奇數時。
那麼 \(x \bmod y < y\),所以 \(x \bmod y < \lfloor \frac x 2 \rfloor = \lceil \frac x 2 \rceil - 1 = x \bmod y\)
所以無論如何 \(\lfloor \frac x 2 \rfloor + 1\) 一定是最優解。
我強烈譴責。。。
#include <cstdio> #include <cmath> int main() { // freopen("mod.in", "r", stdin); // freopen("mod.out", "w", stdout); int t; scanf ("%d", &t); for(int i = 1; i <= t; i++) { int x, k, y; scanf ("%d %d", &x, &k); if(k == 0) { bool flag = false; for(int j = 2; j <= sqrt(x); j++) if(x % j == 0) { y = j; flag = true; break; } if(flag) printf("%d\n", y); else printf("2\n"); } else printf("%d\n", x / 2 + 1); } return 0; }
T2
記憶化一下每步操作後的答案。
我強烈譴責。。。
#include <cstdio>
const int MAXN = 1e5 + 5;
const int MAXL = 15;
char s[MAXL];
int vis[MAXN];
int main() {
freopen("var.in", "r", stdin);
freopen("var.out", "w", stdout);
int n, tot;
scanf ("%d", &n);
tot = 0;
for(int i = 1; i <= n; i++) {
int x;
scanf("%s", s);
scanf ("%d", &x);
if(s[0] == 'A')
tot += x;
else if(s[0] == 'S') {
if(s[1] == 'E')
tot = x;
else if(s[1] == 'U')
tot -= x;
}
else if(s[0] == 'B')
tot = vis[i - x - 1];
vis[i] = tot;
}
for(int i = 1; i < n; i++)
printf("%d ", vis[i]);
printf("%d", vis[n]);
return 0;
}
T3
我強烈譴責。。。
#include <cstdio>
const int MAXL = 5;
const int MAXN = 15;
char s[MAXL];
int num[MAXL][MAXN];
// s = 1, p = 2, m = 3
void init() {
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 9; j++)
num[i][j] = 0;
}
int main() {
// freopen("maj.in", "r", stdin);
// freopen("maj.out", "w", stdout);
int t;
scanf ("%d", &t);
for(int k = 1; k <= t; k++) {
init();
int E = 0, S = 0, W = 0, N = 0, B = 0, F = 0, Z = 0;
for(int j = 1; j <= 14; j++) {
scanf ("%s", s);
if(s[0] == 'E')
E++;
else if(s[0] == 'S')
S++;
else if(s[0] == 'W')
W++;
else if(s[0] == 'N')
N++;
else if(s[0] == 'B')
B++;
else if(s[0] == 'F')
F++;
else if(s[0] == 'Z')
Z++;
else if(s[0] >= '1' && s[0] <= '9') {
int t = s[0] - '0';
if(s[1] == 's')
num[1][t]++;
else if(s[1] == 'p')
num[2][t]++;
else if(s[1] == 'm')
num[3][t]++;
}
}
// printf("%d %d %d %d %d %d %d\n", E, S, W, N, B, F, Z);
// for(int i = 1; i <= 3; i++) {
// for(int j = 1; j <= 9; j++)
// printf("%d ", num[i][j]);
// printf("\n");
// }
if(num[1][1] >= 1 && num[2][1] >= 1 && num[3][1] >= 1
&& num[1][9] >= 1 && num[2][9] >= 1 && num[3][9] >= 1
&& E >= 1 && S >= 1 && W >= 1 && N >= 1 && B >= 1 && F >= 1 && Z >= 1) {
printf("Thirteen\n");
continue;
}
int tot = 0;
if(E == 2)
tot++;
if(S == 2)
tot++;
if(W == 2)
tot++;
if(N == 2)
tot++;
if(B == 2)
tot++;
if(F == 2)
tot++;
if(Z == 2)
tot++;
for(int i = 1; i <= 3; i++)
for(int j = 1; j <= 9; j++)
if(num[i][j] == 2)
tot++;
if(tot == 7) {
printf("Seven\n");
continue;
}
bool flag = false;
for(int i = 1; i <= 3; i++) {
int sum = 0;
for(int j = 1; j <= 9; j++)
sum += num[i][j];
if(sum != 14)
continue;
if(num[i][1] >= 3 && num[i][9] >= 3 && num[i][2] >= 1
&& num[i][3] >= 1 && num[i][4] >= 1 && num[i][5] >= 1
&& num[i][6] >= 1 && num[i][7] >= 1 && num[i][8] >= 1) {
flag = true;
break;
}
}
if(flag)
printf("Nine\n");
else
printf("I don't know.\n");
}
return 0;
}
T4
我們考慮每一個在整個序列排序後位置比當前位置靠前的點。
首先,按照氣泡排序的思路,一次巡視後,比較大的一定會往後走到最後的相對於別的比它更大的數的相對位置。
而比較小的,即需要往前走的則需在很多次巡視後才能到達該位置。
而每次巡視,可以看成某個需要往前走的點最多往前走 \(k - 1\) 步。
那麼我們只需要求需要往前走的點要走個 \(k - 1\) 步才能到排序後應該在的位置。
小學行程問題總會吧,注意向上取整。
我強烈譴責。。。。
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAXN = 1e5 + 5;
int Max(int x, int y) {return x > y ? x : y;}
struct node {
int x, index;
} s[MAXN];
bool cmp(node a, node b) {
if(a.x != b.x)
return a.x < b.x;
return a.index < b.index;
}
int main() {
// freopen("endt.in", "r", stdin);
// freopen("endt.out", "w", stdout);
int t;
scanf ("%d", &t);
while(t--) {
int n, k;
scanf ("%d %d", &n, &k);
for(int i = 1; i <= n; i++) {
scanf ("%d", &s[i].x);
s[i].index = i;
}
int ans = 0;
sort(s + 1, s + n + 1, cmp);
for(int i = 1; i <= n; i++) {
if(s[i].index > i) {
int t = (s[i].index - i) / (k - 1);
if((s[i].index - i) % (k - 1) != 0)
t++;
ans = Max(ans, t);
}
}
printf("%d\n", ans);
}
return 0;
}
其實這套卷子真的很簡單。除了最後一道題比較的考思維以外,其它不都是迴圈結構嗎???
真不知道一些人怎麼考的。