补题4道
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
Alice 和 Bob 在玩一个游戏,他们先从 2000.1.1 到 2024.8.1 这个日期之间(不包括2024.8.1)随意抽取一个日期出来。然后他们轮流对这个日期进行操作:
-
把日期的天数加 1,例如:2000.1.1 变到 2000.1.2
-
把月份加 1,例如:2000.1.1 变到 2000.2.1
其中如果天数超过应有天数则日期变更到下个月的第 1 天。月份超过 12 则变到下一年的1月。而且进行操作2的时候,如果有这样的日期:2000.1.31,则变成了 2000.2.31,这样的操作是非法的,我们不允许这样做。
所有的操作均要考虑历法和闰年的规定。
谁先将日期变到 2024.8.1 谁就赢了。如果超越了指定日期不算获胜。
每次游戏都是 Alice 先操作,问他有没有必胜策略?
输入描述:
第一行一个整数 T,为数据组数(1<=T<=1000)。
接下来一行 X,Y,Z 表示 X 年 Y 月 Z 日。
输出描述:
输出 YES 或者 NO 表示 Alice 是否有必胜策略。
示例1
输入
复制3 2001 11 3 2001 11 2 2001 10 3
3 2001 11 3 2001 11 2 2001 10 3
输出
复制YES NO NO
YES NO NO
#include <iostream>
#include <cstdio>
using namespace std;
int t,x,y,z;
int main(){
scanf("%d",&t);
while(t--){
scanf("%d%d%d",&x,&y,&z);
if((y==9 && z==30) || (y==11 && z==30) || (y+z)%2==0)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
小美想:整个暑假不能全部用来锻炼,也应该收集一些回忆。
整个暑假的回忆将被小美分为两部分:好回忆和坏回忆。
但是并不是所有回忆都可以相安无事的,所以小美也不会随意划分这些回忆的种类。
一个回忆可能会跟其它的一些回忆产生“冲突”,这个“冲突”有一个值 c ,而小美会用波动值来描述整个暑假的美好程度。
只要会产生冲突的两个回忆同时被划分到好回忆或者坏回忆中,小美的波动值就可能发生变化。
具体来说,小美的波动值取决于在最后的划分结果中,同一回忆(好回忆或者坏回忆)种类下最大的那个冲突值。
小美想要自己的暑假尽可能的美好,所以她想请你帮她来划分回忆,使得最后的波动值最小。
输入描述:
输出描述:
输出一个整数,表示最小的波动值 。
示例1
输入
复制4 6 2 3 8 1 3 6 2 3 1 4 3 2 1 2 4 1 4 10
4 6 2 3 8 1 3 6 2 3 1 4 3 2 1 2 4 1 4 10
输出
复制4
4
#include <bits/stdc++.h>
using namespace std;
//think again
const int N = 200010;int p[N];
int find(int x) {
return x == p[x] ? x : p[x] = find(p[x]);
}int main() {
cin.tie(0)->sync_with_stdio(false);
int n, m;
cin >> n >> m;
vector<tuple<int, int, int>> v(m);
for (auto& [a, b, c] : v) {
cin >> a >> b >> c;
}
int l = 0, r = 1e6;
auto check = [&](int mid) {
iota(p, p + n + n + 1, 0);
for (auto [a, b, c] : v) {
if (c > mid) {
int pa = find(a), pb = find(b);
if (pa == pb) return false;
p[find(a + n)] = find(b);
p[find(b + n)] = find(a);
}
}
return true;
};
while (l < r) {
int mid = l + r >> 1;
if (check(mid)) {
r = mid;
} else {
l = mid + 1;
}
}
cout << l << '\n';
return 0;
}
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
Bob 有 n 个数,他想知道任意一个区间内的最大值是多少。
输入描述:
第一行一个整数 n,表示数的个数,其中 n<=10^6;
第二行为 n 个整数。
第三行一个整数 q,表示询问的次数,其中 q<=10^6;
接下来 q 行,每行有一对 L,R,即询问区间 [L,R] 的最大值。
输出描述:
q 行,每一次询问的结果。
示例1
输入
复制5 10 4 6 2 9 3 1 3 2 4 3 5
5 10 4 6 2 9 3 1 3 2 4 3 5
输出
复制10 6 9
10 6 9
备注:
注意此题输入量极大,需要使用输入优化。
#include <iostream>
#include <algorithm>
using namespace std;const int MAXN = 1000010;
int n, q;
int a[MAXN], lg[MAXN], f[MAXN][20];// 快速输入
inline int quickRead() {
int 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 * 10 + ch - '0';
ch = getchar();
}
return x * f;
}int main() {
// 输入优化
ios::sync_with_stdio(false);
cin.tie(nullptr);n = quickRead();
for (int i = 1; i <= n; i++) {
a[i] = quickRead();
f[i][0] = a[i];
}// 预处理对数
lg[1] = 0;
for (int i = 2; i <= n; i++)
lg[i] = lg[i >> 1] + 1;// 构建稀疏表
for (int j = 1; (1 << j) <= n; j++) {
for (int i = 1; i + (1 << j) - 1 <= n; i++) {
f[i][j] = max(f[i][j - 1], f[i + (1 << (j - 1))][j - 1]);
}
}q = quickRead();
while (q--) {
int L = quickRead();
int R = quickRead();
int l = lg[R - L + 1];
int result = max(f[L][l], f[R - (1 << l) + 1][l]);
cout << result << "\n";
}return 0;
}
链接:登录—专业IT笔试面试备考平台_牛客网
来源:牛客网
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 262144K,其他语言524288K
64bit IO Format: %lld
题目描述
暑假来了,对于小美来说,想要锻炼身体,游泳还不够,小美想:她还必须要跑步。
为此,小美在家的周围设置了 n-1 个打卡点,小美每次跑步都需要把这 n-1 个打卡点全部打卡。
但是小美喜欢轻装上阵,所以小美出去跑步时从来不带水杯。
可是小美又容易口渴,所以每次小美打卡完一个打卡点后,都要返回到家中去喝水。
小美第一次出去打卡是从家出发的,小美最后一次打完卡还要回到家中喝水。
况且小美很自律,所以她一定会出去打 n-1 次不同的卡,即便在打卡路上遇到了另一个打卡点,她也不会打卡。
不过小美想:既然已经在假期坚持游泳了,那么跑步上可不可以偷偷懒呢。
所以小美想请聪明的你来帮她想想办法,让她跑步的总路程最短。
输入描述:
输出描述:
输出一个整数,表示跑步的最短总路程。
示例1
输入
复制4 6 1 2 2 2 4 4 1 4 1 4 3 2 3 1 5 1 3 3
4 6 1 2 2 2 4 4 1 4 1 4 3 2 3 1 5 1 3 3
输出
复制29
29
#include<bits/stdc++.h>
using namespace std;
const int N=1e6+10;
int n,m;int d[N],vis[N],di[N];
struct edge{
int v,w;
};
vector<edge> e[N];
priority_queue<pair<int,int>>q;
void spfa(int s)
{
memset(d,0x3f,sizeof d);
memset(vis,0,sizeof vis);
d[s]=0;q.push({0,s});
while(q.size())
{
auto t=q.top();q.pop();
int u=t.second;
if(vis[u]) continue;
vis[u]=1;
for(auto ed:e[u])
{
int v=ed.v;int w=ed.w;
if(d[v]>d[u]+w){
d[v]=d[u]+w;
q.push({-d[v],v});
}
}
}
}
int spfa1(int s)
{
memset(di,0x3f,sizeof di);
memset(vis,0,sizeof vis);
di[s]=0;q.push({0,s});
while(q.size())
{
auto t=q.top();q.pop();
int u=t.second;
if(vis[u]) continue;
vis[u]=1;
for(auto ed:e[u])
{
int v=ed.v;int w=ed.w;
if(di[v]>di[u]+w){
di[v]=di[u]+w;
q.push({-di[v],v});
}
}
}
return di[1];
}
int main()
{
cin>>n>>m;
for(int i=0;i<m;i++)
{
int x,y,z;
cin>>x>>y>>z;
e[x].push_back({y,z});
}
spfa(1);
int h=0;
for(int i=1;i<=n;i++)
{
h+=d[i];
}
for(int i=1;i<=n;i++)
{
h+=spfa1(i);
}
cout<<h<<endl;
}