BCDEFHJ
B. 減成一
鏈接:https://ac.nowcoder.com/acm/contest/5758/B
來源:牛客網
題目描述
存在n個數,每次操作可以任選一個區間使得區間內的所有數字減一。問最少多少次操作,可以讓所有數都變成1。
數據保證一定有解。
輸入描述:
輸入t,代表有t組數據。每組數據輸入n,代表有n個數。接下來一行輸入n個數,數字大小小於1e6。(t<=1000,n<1e5,∑n < 1e6)
輸出描述:
每組數據輸出一個整數代表最少需要操作的次數。
示例1
輸入
1
6
1 3 5 2 7 1
輸出
9
差分數組
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
template<typename T = int>
inline const T read()
{
T x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
return x * f;
}
template<typename T>
inline void write(T x)
{
if (x < 0) { putchar('-'); x = -x; }
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
const int maxn = 1e5 + 10;
int a[maxn];
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("input.txt", "r", stdin);
#endif
int t = read();
while (t--)
{
int n = read();
ll sum = 0;
for (int i = 1; i <= n; i++)
{
a[i] = read() - 1;
sum += max(a[i] - a[i - 1], 0);
}
cout << sum << endl;
}
return 0;
}
C. 面積
鏈接:https://ac.nowcoder.com/acm/contest/5758/C
來源:牛客網
題目描述
如圖所示,正方形周圍接4個半圓,求圖形的面積
輸入描述:
輸入t,代表有t組數據。每組數據輸入正整數x,代表正方形的邊長。(t<100, x<1000)
輸出描述:
輸出圖形面積,並保留2位小數,其中π取3.14。
示例1
輸入
1
1
輸出
2.57
注意用 3.14 代替 PI
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> p;
const double pi = 3.14;
const int inf = 0x3f3f3f3f;
template<typename T = int>
inline const T read()
{
T x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
return x * f;
}
template<typename T>
inline void write(T x)
{
if (x < 0) { putchar('-'); x = -x; }
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("input.txt", "r", stdin);
#endif
int t = read();
while (t--)
{
int x = read();
double s = x * x * (1 + pi / 2);
printf("%.2f\n", s);
}
return 0;
}
D. 扔硬幣
鏈接:https://ac.nowcoder.com/acm/contest/5758/D
來源:牛客網
題目描述
有n枚硬幣,每枚硬幣扔出來是正面和反面的概率各佔50%。小明同時扔下了n枚硬幣後,已知至少有m枚硬幣是反面。請問恰好有k枚硬幣是正面的概率是多少。
輸入描述:
輸入t,代表有t組數據。每組數據輸入一個數n,m,k,代表有n枚硬幣,拋出以後至少有m枚是反面的情況下,恰好有k個正面的概率。
(t<=1000,n<1e5,m<=1000,k<=n)
輸出描述:
對於結果是p/q,輸出分數取模1e9+7後的結果。
示例1
輸入
1
10 3 5
輸出
797520667
概率 逆元
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
template<typename T = int>
inline const T read()
{
T x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
return x * f;
}
template<typename T>
inline void write(T x)
{
if (x < 0) { putchar('-'); x = -x; }
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
const int mod = 1e9 + 7;
const int maxn = 1e5 + 10;
ll fac[maxn];
void init()
{
fac[0] = 1;
for (int i = 1; i <= 1e5; i++)
fac[i] = fac[i - 1] * i % mod;
}
ll qpow(ll x, ll k)
{
ll res = 1;
while (k)
{
if (k & 1) res = res * x % mod;
x = x * x % mod; k >>= 1;
}
return res;
}
ll com(int n, int m)
{
return fac[n] * qpow(fac[m], mod - 2) % mod * qpow(fac[n - m], mod - 2) % mod;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("input.txt", "r", stdin);
#endif
int t = read();
init();
while (t--)
{
int n = read(), m = read(), k = read();
if (n < m + k)
{
cout << 0 << endl;
continue;
}
ll a = com(n, k), b = qpow(2, n);
for (int i = 0; i < m; i++) b = (b - com(n, i) + mod) % mod;
ll res = a * qpow(b, mod - 2) % mod;
cout << res << endl;
}
return 0;
}
E. 賽馬
鏈接:https://ac.nowcoder.com/acm/contest/5758/E
來源:牛客網
題目描述
一天小明與他同學準備賽馬,他們每人有n匹馬,每匹馬有一個固定的戰力值,戰力值高的馬會戰勝戰力值低的馬並贏得比賽。每匹馬只能出場比賽一次。小明偷看到了他對手每匹馬的出場順序,小明在更改自己馬出場順序後最多能贏多少場比賽。
輸入描述:
輸入t,代表有t組數據。每組數據輸入正整數n,每人的馬匹數量。下一行輸入n個值a[i],代表小明每匹馬的戰力值。接下來一行輸入n個值b[i],代表對手按順序出場的每匹馬的戰力值。(t<=10, n<1000,1<=i<=n,a[i]<1e6,b[i]<1e6)
輸出描述:
小明在更改馬匹出場順序後,最多能贏的場數。
示例1
輸入
1
3
5 8 8
4 7 10
輸出
2
二分查找 multiset 的妙用
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
multiset<int> s;
template<typename T = int>
inline const T read()
{
T x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
return x * f;
}
template<typename T>
inline void write(T x)
{
if (x < 0) { putchar('-'); x = -x; }
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("input.txt", "r", stdin);
#endif
int t = read();
while (t--)
{
int n = read(), cnt = 0;
s.clear();
for (int i = 0; i < n; i++) s.insert(read());
for (int i = 0; i < n; i++)
{
int v = read();
auto it = s.upper_bound(v);
if (*it > v)
{
s.erase(it);
cnt++;
}
}
cout << cnt << endl;
}
return 0;
}
F. 三角形
鏈接:https://ac.nowcoder.com/acm/contest/5758/F
來源:牛客網
題目描述
小明有一根長度爲a的木棒,現在小明想將木棒分爲多段(每段木棒長度必須爲整數),
使得分隔後的木棍中,取出的任意三段都不能構成三角形,小明想知道木棒最多被分成幾段?
輸入描述:
輸入數據的第一行是t,表示數據的組數, 接下來每組數據輸入一個a
(t<=1000, 1 <= a < 2^64 - 1)
輸出描述:
對於每組輸入樣例,打印木棒最多被分爲多少段
示例1
輸入
2
1
3
輸出
1
2
斐波那契數列任意兩項和唯一
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
template<typename T = ull>
inline const T read()
{
T x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
return x * f;
}
template<typename T>
inline void write(T x)
{
if (x < 0) { putchar('-'); x = -x; }
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("input.txt", "r", stdin);
#endif
ll t = read();
while (t--)
{
ull a = read(), now = 1, rec = 1, last = 0;
int cnt = 0;
while (a >= now)
{
a -= now;
rec = now;
now += last;
last = rec;
cnt++;
}
cout << cnt << endl;
}
return 0;
}
H. 直線
鏈接:https://ac.nowcoder.com/acm/contest/5758/H
來源:牛客網
題目描述
平面上存在n條直線。請問n條直線在平面上最多存在多少交點。
輸入描述:
輸入數據的第一行是t,表示數據的組數(t < 100), 接下來每組數據輸入一個n(1<=n <= 1e15)
輸出描述:
對於每組輸入樣例,打印n條直線最多有多少個交點
示例1
輸入
2
1
2
輸出
0
1
防溢出
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef __int128 lll;
typedef pair<int, int> p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
template<typename T = lll>
inline const T read()
{
T x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
return x * f;
}
template<typename T>
inline void write(T x)
{
if (x < 0) { putchar('-'); x = -x; }
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("input.txt", "r", stdin);
#endif
int t = read();
while (t--)
{
lll n = read();
write(ans = n * (n - 1) / 2);
putchar(10);
}
return 0;
}
J. 最大值
鏈接:https://ac.nowcoder.com/acm/contest/5758/J
來源:牛客網
題目描述
有一個字符串s,對於字符串中一個非前綴子串恰好爲字符串的前綴我們稱之爲ac串。
請問給出一個字符串他的ac串最大長度爲多少
輸入描述:
輸入數據第一行是t,表示數據的組數,接下來每組數據輸入一個字符串s
(t<=10,s<=1e5)
輸出描述:
輸出最大長度
示例1
輸入
2
aaaaa
abacc
輸出
4
1
說明
aaaab的ac串是aaa(2:4)
acac的ac串是ac(3:4)
KMP 算法 next 數列的性質
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
int nxt[maxn];
char s[maxn];
template<typename T = int>
inline const T read()
{
T x = 0, f = 1; char ch = getchar();
while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
while (ch >= '0' && ch <= '9') { x = (x << 3) + (x << 1) + ch - '0'; ch = getchar(); }
return x * f;
}
template<typename T>
inline void write(T x)
{
if (x < 0) { putchar('-'); x = -x; }
if (x > 9) write(x / 10);
putchar(x % 10 + '0');
}
void getNext(size_t len)
{
memset(nxt, 0, sizeof(nxt));
for (int i = 2, j = 0; i <= len; i++)
{
while (j && s[i] != s[j + 1]) j = nxt[j];
if (s[i] == s[j + 1]) j++;
nxt[i] = j;
}
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("input.txt", "r", stdin);
#endif
int t = read();
while (t--)
{
scanf("%s", s + 1);
size_t len = strlen(s + 1);
getNext(len);
int res = 0;
for (int i = 1; i <= len; i++)
res = max(res, nxt[i]);
cout << res << endl;
}
return 0;
}