A 握手問題
簡單模擬,答案為:1204 5pts
B 小球反彈
數學,最重要的一點,不考慮反彈,一直讓小球走,直到達到一個頂點,它就會反彈回去。
所以問題就變成了擴充套件這些方塊,直到滿足小球的角度,讓小球能達到另一個頂點。
\(233333 \times 15 a= 343720 \times 17b\)
解出來 a 和 b就知道我們要延長多少塊了,這裡需要約分,建議使用最大公約數求一下,然後直接用勾股定理,這裡用excel很好求。
答案:1100325199.77 5pts
C 好數
暴力可過,時間複雜度 \(O(7\times10^7)\) 10pts
int check(int x)
{
int cnt = 1;
while (x)
{
int p = x % 10;
if (cnt % 2)
{
if (p % 2 == 0) return false;
}
else
{
if (p % 2 == 1) return false;
}
x /= 10;
cnt++;
}
return true;
}
void solve()
{
cin >> n;
int res = 0;
for (int i = 1; i <= n; i++)
if (check(i)) res++;
cout << res;
}
D R格式
高精度+快速冪,但是沒必要,5分而已 5pts
// 5分程式碼
long long n;
double p;
void solve()
{
cin >> n >> p;
double res = p * pow(2, n);
cout << (long long)(res + 0.5);
}
E 寶石組合
好像是分解質因數,比賽時看不出來,直接暴力3迴圈拿30% 4.5pts
這裡的公式可以化簡,化簡後就沒有最小公倍數了,只有最大公約數。
const int N = 100010;
int a[N];
int n;
int gcd(int a, int b)
{
return b ? gcd(b, a % b) : a;
}
int calc(int a, int b, int c)
{
return gcd(a, c) * gcd(b, c) / gcd(a * b / gcd(a, b), c);
}
void solve()
{
cin >> n;
for (int i = 1; i <= n; i++) cin >> a[i];
sort(a + 1, a + 1 + n);
int res = 0;
int maxa, maxb, maxc;
for (int i = 1; i <= n - 2; i++)
for (int j = i + 1; j <= n - 1; j++)
for (int k = i + 2; k <= n; k++)
{
if (res < calc(a[i], a[j], a[k]) && i != j && j != k && i != k)
{
maxa = a[i];
maxb = a[j];
maxc = a[k];
res = calc(a[i], a[j], a[k]);
}
}
cout << maxa << ' ' << maxb << ' ' << maxc;
}
F 數字接龍
看資料範圍,一眼暴力dfs
dfs的條件很多,很多細節,比賽時寫的程式碼在民間測試只過了60%不知道哪裡錯了 8pts
const int N = 15;
int g[N][N], dist[N][N];
bool st[N][N];
int n, k;
int dx[8] = {-1, -1, 0, 1, 1, 1, 0, -1};
int dy[8] = {0, 1, 1, 1, 0, -1, -1, -1};
bool dfs(int x, int y, int op, int cnt)
{
if (x == n && y == n && cnt == n * n)
{
return true;
}
for (int i = 0; i < 8; i++)
{
int a = dx[i] + x, b = dy[i] + y, c = (op + 1) % k;
if (a < 1 || a > n || b < 1 || b > n) continue;
if (st[a][b]) continue;
if (g[a][b] != c) continue;
if (a + b < x + y) continue;
st[a][b] = true;
dist[x][y] = i;
if (dfs(a, b, c, cnt + 1)) return true;
st[a][b] = false;
}
return false;
}
void solve()
{
cin >> n >> k;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
cin >> g[i][j];
st[1][1] = true;
if (!dfs(1, 1, 0, 1))
{
cout << -1 << endl;
return;
}
int i = 1, j = 1;
while (!(i == n && j == n))
{
int p = dist[i][j];
cout << p;
i = i + dx[p];
j = j + dy[p];
}
}
G 爬山
聽說是錯題,我用的優先佇列在民間資料上測試AC了 20pts
priority_queue<int> heap;
int n, p, q;
void solve()
{
cin >> n >> p >> q;
while (n--)
{
int x;
cin >> x;
heap.push(x);
}
while (p --)
{
int t = heap.top();
heap.pop();
t = sqrt(t);
heap.push(t);
}
while (q--)
{
int t = heap.top();
heap.pop();
t /= 2;
heap.push(t);
}
int res = 0;
while (heap.size())
{
res += heap.top();
heap.pop();
}
cout << res;
}
H 拔河
看錯題了,以為是人必須選完,但是可以有人不選的 0pts