2020年浙大城市学院新生程序设计竞赛(同步赛)
B Xjj’s Touching Value
题目描述:
题意:
给你一个函数F(x), a, b, n,当x属于[0, n]时,求F(x)最大值,还得是最简分式的形式
思路:
就是把x从0 到 n遍历一遍,找到最大值,然后用最大值对应的x,求最小公约数,实现最简分式
#include<bits/stdc++.h>
#define fast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
using namespace std;
typedef long long ll;
int main()
{
int m, a, b, n;
int ansa, ansb;
cin>>m;
while(m--)
{
cin>>a>>b>>n;
double manx = -1e9;
for(int i = 0; i <= n; i++)
{
if((a * i + b) * 1.0 / pow(2, i) > manx)//pow(x,y)函数用来求x的y次方
{
manx = (a * i + b) * 1.0 / pow(2, i);//更新最大值
ansa = a * i + b;//记录
ansb = pow(2, i);//记录
}
}
if(ansa % ansb == 0) cout<<ansa/ansb<<'\n';//整除的时候进行特判,这个时候就不用写成分式的形式
else
{
if(manx < 0) cout<<'-';//特判一步小于0的情况,好加负号
int tmp =__gcd(ansa, ansb);//求最大公约数,实现最简分式
cout<<abs(ansa / tmp)<<"/"<<abs(ansb / tmp)<<'\n';// abs()是绝对值函数
}
}
return 0;
}
F Drinking Time II
题目描述:
Hile 来到了鸽子转转转酒吧,向酒保 Boboge 点了亿杯红酒、114514 杯红茶、012346789 杯耗子尾汁。Boboge 作为一名正常的上班族酒保,当然拒绝了 Hile 的不合理要求,并且给了 Hile 一道题让他自己玩去。
题目是这样的:给出A,B,C三种饮料各自的数量,有三种鸡尾酒D,E,F的调制规则:
-
1A+1B=1D(使用一杯A饮料和一杯B饮料可以调制出一杯D鸡尾酒,下面两种规则以此类推)
-
1A+1C=1E
-
1C+1C=1F
现在,Hile 要求出能调出的鸡尾酒的最大数量,但是Hile 太菜了,于是便来向你寻求帮助,你能告诉她答案吗?
思路:
B只能配A,所以先匹配,A能匹配B,也能匹配C,然后C自己能匹配自己,所以第二个匹配B,最后匹配C
#include<bits/stdc++.h>
using namespace std;
int main()
{
int a, b, c;
cin>>a>>b>>c;
int sum = 0;
if(a > b)
{
a = a - b;
sum += b;
if(a > c)
{
sum+=c;
}
else
{
sum+=a;
sum+=(c - a) / 2;
}
}
else
{
sum += a;
sum += c / 2;
}
cout<<sum;
return 0;
}
L No 114514
题意:
给你一个n,然后输入n个数,且这n个数仅为1、4、5,你可以进行最多n/6向上取整次操作对数进行改变,改变的数也仅为1、4、5,使得该串数不会出现114514的序列
思路:
遍历一遍,判断哪个地方出现114514,就进行修改,修改的方式可以有很多种,但是不能把第一个1改成4或者5,因为这样出现了114514的后缀,前面就又可能出现114514的前缀,刚好合起来是114514,就会wa
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n;
int tr[200005];
cin>>n;
for(int i = 0; i < n; i++)
{
cin>>tr[i];
}
for(int i = 0; i < n; i++)
{
if(tr[i]==1 && tr[i + 1]==1 && tr[i + 2]==4 && tr[i + 3] == 5 && tr[i + 4] == 1 && tr[i + 5] == 4)
{
tr[i +4] = 5;
i+= 5;
}
}
for(int i = 0; i < n; i++)
cout<<tr[i]<<' ';
}
H Bsq AK ZUCCPC
题目描述:
新生赛开赛在即,Kwords打算预测每道题的过题人数,现在他想知道如果按照他预测的过题数据,会有多少人能够AK(全部通过)或爆零(无法通过任何一道题)呢。因为Kwords并不知道榜单实际的过题情况,所以希望你能帮助他预测AK和爆零的人数区间。
题意:给你N,M,N是有几个题,M是有几个人参加比赛,然后是N个题的过题数,让你求AK(就是全部AC)的人的取值范围和爆0 的人数的取整范围。
思路:
这是一道思维题……
首先对于AK的人数的上下界
-
对于上界,应该为tr数组的最小值
-
对于下界,有两种方法,一种是当所有题通过的人数sum大于题目数减去1乘以参加人数的时候,此时上界为二者的差,为什么呢?因为求下界,要尽可能让过题的人分散开,让每个题过题的人不一样,而当sum大于那个数时,就是再怎么分散开,都会有人重,就是没法让人不AK;而当sum小于那个数的时候,就可以让每个题的人完全分散开,就是0。另一种方法是官方的逆向思维:
(吃饭前我也是这么做,结果吃了饭回来忘了,就在路上又想了第一个法子,手动狗头)
再求爆0 的范围
-
上界:用总人数减去tr数组的最大值即可
-
下界:就是比所有的过题数sum与人数M的大小,如果大于M,则是0,否则就是M - sum.
#include<bits/stdc++.h> #define fast ios::sync_with_stdio(false),cin.tie(0),cout.tie(0) using namespace std; typedef long long ll; int tr[100055]; int main() { int n, m, t; cin>>t; while(t--) { ll sum = 0; memset(tr, 0, sizeof(0));//每次都得给数组清0 cin>>n>>m; for(int i = 0; i < n; i++) { cin>>tr[i]; sum+=tr[i];//求和 } sort(tr, tr + n);//排序 if(sum <= (n - 1) * m) cout<<0<<' '; else cout<<sum - (n - 1) * m<<' '; cout<<tr[0]<<'\n'; if(sum > m) cout<<0<<' '; else cout<<m - sum<<' '; cout<<m - tr[n - 1]<<'\n'; } return 0; }
-
m<<’ ‘;
cout<<tr[0]<<’\n’;
if(sum > m) cout<<0<<’ ‘;
else
cout<<m - sum<<’ ‘;
cout<<m - tr[n - 1]<<’\n’;
}
return 0;
}