牛客周赛 Round 51
A 小红的同余
链接:https://ac.nowcoder.com/acm/contest/86034/A
来源:牛客网
题目描述
给出一个奇数 𝑚,请找出一个整数 𝑥(0≤𝑥<𝑚),使得 2𝑥≡1(mod𝑚),也就是 2𝑥 除以
𝑚 的余数是 1。你需要输出这个整数 𝑥。
可以证明,这样的整数 𝑥 存在且唯一。
输入描述:
第一行一个整数 𝑚,表示给出的奇数。
3≤𝑚≤109
输出描述:
输出一个整数 𝑥(0≤𝑥<𝑚),满足 2𝑥≡1(mod𝑚)。
示例1
输入
3
输出
2
说明
2×2≡1(mod3)
题解
签到
#include<bits/stdc++.h>
using namespace std;
int m;
int main(){
cin>>m;
cout<<(m+1)/2<<endl;
return 0;
}
B 小红的三倍数
链接:https://ac.nowcoder.com/acm/contest/86034/B
来源:牛客网
题目描述
现在有𝑛个整数,需要寻找一种拼接方式,将所有整数首尾相连,是否存在一种方式让拼接后的整数是3的倍数。
输入描述:
第一行给出一个𝑛,代表有多少个数字。
第二行输入𝑛个整数𝑎𝑖 。1≤𝑛≤100 1≤𝑎𝑖≤100
输出描述:
如果有一种拼接方式让这个数是3的倍数,那么就输出“YES”,否则输出 “NO”。
示例1
输入
3
12 3 7
输出
NO
说明
不存在一种拼接方式让这个数是3的倍数。
示例2
输入
3
12 3 6
输出
YES
说明
1263 是 3 的倍数。
题解
不会做的人建议回小学哈
四年级知识
#include<bits/stdc++.h>
using namespace std;
int n,sum;
string a;
int main(){
int i,j,k;
cin>>n;
for(i=1;i<=n;i++){
cin>>a;
for(j=0;j<a.length();j++)
sum+=a[j]-'0';
}
if(sum%3==0)printf("YES\n");
else printf("NO\n");
return 0;
}
C 小红充电
链接:https://ac.nowcoder.com/acm/contest/86034/C
来源:牛客网
题目描述
小红手机充满电是100%,现在手机有𝑥%的电,不充电玩手机每分钟会损失𝑦%的电,充着电玩手机每分钟会充𝑎%的电,充着电不玩手机每分钟会充𝑏%的电,电量不高于𝑡%开始触发超级充电(充到𝑡%之后仍然保持超级充电),超级充电时不能玩手机,每分钟会充𝑐%的电。小红现在有急事要出门,问最短多长时间会充满电?
输入描述:
第一行输入6个整数𝑥,𝑦,𝑡,𝑎,𝑏,𝑐。1≤𝑥,𝑦,𝑡≤100 1≤𝑎≤𝑏≤𝑐≤100
输出描述:
输出小红充满电的最短时间,如果你的答案与标准答案的绝对误差不超过10−6 ,则视为正确。
示例1
输入
10 2 20 3 4 5
输出
18.000000000
说明
已经触发了超级充电,所以不玩手机,每分钟充5%的电,所以18分钟充满电。
题解
分类讨论下,没什么难点
#include <bits/stdc++.h>
using namespace std;
double x,y,t,a,b,c;
signed main()
{
int i,j,k;
cin>>x>>y>>t>>a>>b>>c;
double ans=0;
if (x<=t) {
ans = (100 - x) / c;
} else {
ans = (100 - x) / b;
double mid = (x - t) / y + (100 - t) / c;
ans = min(ans, mid);
}
printf("%.20lf",ans);
return 0;
}
D 小红的 gcd
链接:https://ac.nowcoder.com/acm/contest/86034/D
来源:牛客网
题目描述
给两个正整数𝑎,𝑏,输出他们的最大公约数gcd (𝑎,𝑏)。
输入描述:
第一行一个正整数 𝑎。
第二行一个正整数 𝑏。
𝑙𝑒𝑛表示𝑎的十进制位数,1≤𝑙𝑒𝑛≤106 。
1≤𝑏≤109 。
输出描述:
输出一个整数,表示gcd (𝑎,𝑏)。
示例1
输入
12345678
12
输出
6
题解
这个写的超级详细,至于原理我也第一次见到,当作积累哈
#include<bits/stdc++.h>
using namespace std;
#define int long long
string a;
int b,n;
signed main(){
int i,j,k;
cin>>a>>b;
for(i=0;i<a.size();i++)
n=(n*10+a[i]-'0')%b;
cout<<gcd(n,b)<<endl;
return 0;
}
E 小红走矩阵
链接:https://ac.nowcoder.com/acm/contest/86034/E
来源:牛客网
题目描述
给定𝑛×𝑛的矩阵,矩阵中的每个元素都是正整数,小红能当前位于左上角(1,1),每次可以从
(𝑥,𝑦) 走到 (𝑥+1,𝑦)、(𝑥,𝑦+1)、(𝑥−1,𝑦)、(𝑥,𝑦−1),但不能走出矩阵。小红希望找到一条到右下角(𝑛,𝑛)的路径,定义路径权值为路径上经过的每个点的最大值,求所有路径中的最小路径权值。
输入描述:
第一行一个整数𝑛,表示矩阵的大小。
接下来𝑛行,每行𝑛个整数,表示矩阵中的元素𝑎𝑖𝑗 。1≤𝑛≤500 1≤𝑎𝑖𝑗≤109 。
输出描述:
输出一个整数,表示所有路径中的最小路径权值。
示例1
输入
3
3 2 1
6 5 4
9 8 7
输出
7
说明
先一直往右走,再一直往下走,路径上的最大值为7。
题解
模板提,跑一边Dijsktra就行,而且不需要啥优化
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define pii pair<int, pair<int, int> >
int n,a[505][505],f[505][505];
bool st[505][505];
int vis[][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
bool in(int x, int y) {
return x >= 1 && x <= n && y > 0 && y <= n;
}
void dfs(int x, int y) {
f[x][y] = a[x][y];
st[x][y] = true;
priority_queue<pii, vector<pii>, greater<pii> > q;
q.push({a[x][y], {x, y}});
while(q.size()) {
auto t = q.top();
q.pop();
int tt = t.first;
x = t.second.first;
y = t.second.second;
for (int i = 0; i < 4; i ++) {
int tx = x + vis[i][0];
int ty = y + vis[i][1];
if (in(tx, ty) && !st[tx][ty])
{
st[tx][ty] = true;
f[tx][ty] = max(f[x][y], a[tx][ty]);
q.push({f[tx][ty], {tx, ty}});
}
}
}
}
signed main() {
int i,j,k;
cin>>n;
for (i=1;i<=n;i++) {
for (j=1;j<=n;j++) {
cin>>a[i][j];
}
}
memset(f, 0x3f, sizeof f);
dfs(1, 1);
cout << f[n][n] << endl;
return 0;
}
F 小红的数组
链接:https://ac.nowcoder.com/acm/contest/86034/F
来源:牛客网
题目描述
小红有一个数组,这个数组中有 𝑛 个数 𝑎𝑖。
小红有 𝑞 次询问,每次询问给定一个区间 [𝑙,𝑟],询问区间连续子段和的绝对值最大是多少,即区间存在 𝑥,𝑦 使得 𝑙≤𝑥≤𝑦≤𝑟,求最大的 abs(𝑎[𝑥]+𝑎[𝑥+1]+…+𝑎[𝑦])是多少。
输入描述:
第一行输入一个整数 𝑛 表示数组的长度。
第二行输入 𝑛 个整数 𝑎𝑖 表示数组的元素。
第三行输入一个整数 𝑞 表示询问的次数。
接下来 𝑞 行,每行输入两个整数 𝑙,𝑟 表示询问的区间。
1≤𝑛,𝑞≤5×105 −109≤𝑎𝑖≤109 1≤𝑙≤𝑟≤𝑛
输出描述:
输出 𝑞 行,每行输出一个整数表示对应询问的答案。
示例1
输入
5
1 2 -3 -4 5
3
1 3
2 4
3 5
输出
3
7
7
题解
额,模板,RMQ或者线段树/树状数组都可以.
ST 表也行
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int M=500005;
int dx[4]={0,0,1,-1},dy[4]={1,-1,0,0};
int a[M],n,m;
int st1[M][32],st2[M][32];
int qurey(int l,int r){
int t=log2(r-l+1);
int ma=max(st1[l][t],st1[r-(1<<t)+1][t]);
int mi=min(st2[l][t],st2[r-(1<<t)+1][t]);
return ma-mi;
}
signed main(){
int i,j,k;
cin>>n;
for(i=1;i<=n;i++) {
cin>>a[i];
a[i]+=a[i-1];
}
for(i=1;i<=n;i++) {
st1[i][0]=a[i];
st2[i][0]=a[i];
}
int t=log2(n);
for(j=1;j<=t;j++)
for(i=0;i+((1<<j)-1)<=n;i++){
st1[i][j]=max(st1[i][j-1],st1[i+(1<<(j-1))][j-1]);
st2[i][j]=min(st2[i][j-1],st2[i+(1<<(j-1))][j-1]);
}
cin>>m;
while(m--){
int l,r;
cin>>l>>r;
cout<<qurey(l-1,r)<<endl;
}
return 0;
}