模拟赛5(普及)
题号 | 题目 |
---|---|
T1 | 购物 |
T2 | 交换 |
T3 | 最少移动 |
T4 | 飞行棋 |
1.购物
解题思路
暴力
AC代码
#include<cstdio>
using namespace std;
int t,n,k,x;
int main()
{
scanf("%d",&t);
while(t--)
{
scanf("%d%d%d",&n,&k,&x);
int o=0,s=0;
while(n>0)//暴力
{
n--;//数量-1
o++;
s+=x;//钱
if(o>=k){
n--;o=0;}
}
printf("%d\n",s);
}
return 0;
}
2.交换
解题思路
复制一遍s加到s后面
然后一个一个去找
看最长的全是1的区间
注意:要和s最开始的长度取min,否则样例全是1会错
AC代码
#include<iostream>
#include<cstdio>
using namespace std;
int ans,o;
string s;
int main()
{
cin>>s;
s+=s;//复制
int l=s.size();
for(int i=0;i<l;i++)
{
if(s[i]=='1')//求全是1的区间长度
{
if(s[i]==s[i-1])o++;
else o=1;
}
else o=0;
ans=max(ans,min(l/2,o));//取min
}
printf("%d",ans);
return 0;
}
3.最少移动
解题思路
我们可以先求出它们的平均值
如果平均值不是整数,就输出-1
然后我们求出每个点到平均值的次数
记住如果更改了这个点,那么它的下一个点要进行相反更改
AC代码
#include<cstdio>
#include<cmath>
using namespace std;
long long t,a[100005];
int main()
{
scanf("%lld",&t);
while(t--)
{
long long n,s=0,ans=0;
scanf("%lld",&n);
for(long long i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
s+=a[i];//求和
}
if(s%n!=0)printf("-1\n");//平均值特判
else
{
s/=n;
for(long long i=1;i<=n;i++)
{
ans+=abs(s-a[i]);//加距离
a[i+1]-=(s-a[i]);//减距离
}
printf("%lld\n",ans);
}
}
return 0;
}
4.飞行棋
解题思路
奉上ZYCdalao的思路
未做
模拟赛5(提高)
前言:莫名其妙就做了,以为能加Rating,但是还减了不少
题号 | 题目 |
---|---|
T1 | 三元组计数 |
1.三元组计数
解题思路
暴力枚举每一个数
减少点枚举范围就行了
AC代码
#include<cstdio>
using namespace std;
int n,ans;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n-2;i++)
{
int a=i;//a的值
for(int j=2;j<=n/a;j++)
{
int b=a*j; //b的值
for(int k=2;k<=n/b;k++)
ans++;
}
}
printf("%d",ans);
return 0;
}
总结
考试 (普及)
预估:100+100+100+0=300
实际:100+100+80+0=280
考试 (提高)
预估:50
实际:100
能去尝试提高,要开long long