BCDEFHJ
链接: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
using namespace std;
typedef long long ll;
typedef pair p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
template
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
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;
}
链接: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
using namespace std;
typedef long long ll;
typedef pair p;
const double pi = 3.14;
const int inf = 0x3f3f3f3f;
template
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
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;
}
链接: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
using namespace std;
typedef long long ll;
typedef pair p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
template
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
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;
}
链接: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
using namespace std;
typedef long long ll;
typedef pair p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
multiset s;
template
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
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;
}
链接: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
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
template
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
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;
}
链接: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
using namespace std;
typedef long long ll;
typedef __int128 lll;
typedef pair p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
template
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
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;
}
链接: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
using namespace std;
typedef long long ll;
typedef pair p;
const double pi = acos(-1.0);
const int inf = 0x3f3f3f3f;
const int maxn = 1e5 + 10;
int nxt[maxn];
char s[maxn];
template
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
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;
}