文章目录
题目来源
链接:https://ac.nowcoder.com/acm/contest/88527/A
来源:牛客网
A 日历游戏
题目描述
轮流对这个日期进行操作:
1.把日期的天数加 1,例如:2000.1.1 变到 2000.1.2
2.把月份加 1,例如:2000.1.1 变到 2000.2.1
思路
就是一个简单的博弈,其实就是计算一下加多少次就行了
代码
int main()
{
int t;
cin>>t;
while(t--)
{
int x,y,z;
cin>>x>>y>>z;
if((y==9||y==11)&&z==30)
cout<<"YES"<<'\n';
else if((y+z)%2==0)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
}
B 学生分组
题目描述
有一个含有 n 个元素的随机序列,如果一个序列中所有元素均在 [L,R] 区间内,则称其为一个好的序列,现在每次你可以在使其中一个数+1,另一个数-1,问最少要多少次才可以使随机序列成为一个好的序列。
解题思路
主要就两种情况,一种就是完全不可能的(考虑一下减少,增加的极值);另一种就是计算边界的差值比较一下大小
代码
long long m[1000050];
int main()
{
long long a,b,c,d,e,f;
cin>>a;
d=0;
for(int i=1;i<=a;i++)
{
cin>>m[i];
d=d+m[i];
}
cin>>b>>c;
if(d>a*c||d<a*b)cout<<"-1";//超出界限
else
{
e=0;
f=0;
for(int i=1;i<=a;i++)
{
if(m[i]>c)e=e+m[i]-c;//右区间
if(m[i]<b)f=f+b-m[i];//左区间
}
cout<<max(e,f);
}
}
D 区间问题1
题目描述
Alice 有 n 个数,她可以对这 n 个数执行以下两种操作:
1. 将区间 [L,R] 上的所有数加上 d
2. 查询第 x 个数的值
解题思路
就是用循环在区间加上,查询第x个(这道题数据比较水)
代码
#include<iostream>
#include<algorithm>
using namespace std;
int main()
{
int n;
cin>>n;
int a[n+20];
for(int i=0;i<n;i++)
{
cin>>a[i];
}
int q;
cin>>q;
while(q>0)
{
int h,l,r,d,x;
cin>>h;
if(h==1)//操作1
{
cin>>l>>r>>d;
for(int i=l-1;i<r;i++)
{
a[i]+=d;//加的,
}
q--;//输入区间
}
else//操作2
{
cin>>x;
cout<<a[x-1]<<'\n';
q--;//或查询都更新;
}
}
return 0;
}
E 哥德巴赫猜想
题目描述
任何一个奇数都可以是由三个质数相加得到的,让前两个尽可能小
思路
先素数判断,两个循环让第三个数等于总数减前两个数
代码
#define int long long
using namespace std;
int isPrime(int x)
{
if (x<=1) return 0;
if (x<=3) return 1;
if (x%2==0||x%3==0) return 0;
for (int i=5;i<= sqrt(x); i+=6)
if (x%i==0||x%(i+2)==0)
return 0;
return 1;
}
signed main()
{
int t;
cin>>t;
while(t--)
{
int n;
cin>>n;
int found=0;
for (int l=2;l<=n/3; ++l)
{
if (!isPrime(l))
continue;
for (int j=l;j<=(n-l)/2;++j)
{
if(!isPrime(j))
continue;
int k=n-l-j;//保证前两个最小第三个最大
if(k>=j&&isPrime(k))
{
cout<<l<<' '<<j<<' '<<k<<'\n';
found=1;
break;
}
}
if(found==1) //找到就推出循环
break;
}
if(found==0) //找不到
cout<<"-1"<<'\n';
}
return 0;
}
G 爬楼梯
题目描述
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1-3 个台阶。你有多少种不同的方法可以爬到楼顶呢?
思路
dp,当前数量楼梯等于前一个楼梯的数量,注意每次可以走几个楼梯
代码
const int MOD = 1000000007;
signed main() {
int n;
cin >> n;
vector<int> dp(n + 1, 0);
dp[0] = 1;
if (n >= 1) dp[1] = 1;
if (n >= 2) dp[2] = 2;//对前两个楼梯方法数预处理
for (int i = 3; i <= n; i++)
dp[i] = (dp[i-1] + dp[i-2] + dp[i-3]) % MOD;//因为可以走1个,两个,三个
cout << dp[n] << endl;
return 0;
}
H 区间问题2
题目描述
Bob 有 n 个数,他想知道任意一个区间内的最大值是多少。
思路
就是ST表问题
ST的解释可以看一下这个博主
代码
int f[N][21];
int main()
{
ios::sync_with_stdio(0);//这里必须加快读快些,不然过不了
cin.tie(0),cout.tie(0);
int n;
cin>>n;
for(int i=1;i<=n;i++)
cin>>f[i][0];
for(int i=1;i<=20;i++)
for(int j=1;j+(1<<i)-1<=n;j++)
f[j][i]=max(f[j][i-1],f[j+(1<<(i-1))][i-1]);
int m;
cin>>m;
while(m--)
{
int l,r;
cin>>l>>r;
int k=log2(r-l+1);
cout<<max(f[l][k],f[r-(1<<k)+1][k])<<"\n";
}
return 0;
}
I 小美想打音游
题目描述
把所有数变成同一个数,再加一个魔力值就可以达到满分
思路
求中位数,算一下每一个数变为和中位数相等需要多少,最后加一
代码
int compare(const void *a, const void *b)
{
return (*(int*)a - *(int*)b);
}
int main()
{
int n;
cin>>n;
int scores[1000060];
for (int i = 0; i < n; i++)
cin>>scores[i];
qsort(scores, n, sizeof(int), compare);
int median = scores[n / 2];
long long Cost = 0;
for (int i = 0; i < n; i++)
Cost += abs(scores[i] - median);
cout<<Cost+1;
return 0;
}
J 平方根
题目描述
思路
直接平方根函数
代码
int main() {
int t;
cin>>t;
while(t--)
{
long long n;
cin >> n;
cout << (long long)sqrt(n) << endl; //不直接强制转化为整形,可能出差错
}
return 0;
}