A题:Exciting Bets
题意:给定a,b。有操作1.使a和b同时+1,操作2.使a和b同时-1。求无限次操作后最大的gcd(a,b)。
数据范围:多组输入t<5e3,a,b<1e18
样例解释:
4
8 5
1 2
4 4
3 9
输出:
3 1
1 0
0 0
6 3
第一组:进行一次操作1,有gcd(9,6)=3
第二组:不进行操作,有gcd(1,2)=1
第三组:进行无限次操作1,由题输出"0 0"
第四组:进行三次操作1,有gcd(6,12)=6
思路:题目可以进行无限次+1或-1操作,即求gcd(a+x,b+x)。由公式gcd(a,b)=gcd(a-b,b)可知,gcd(a+x,b+x)=gcd(a+x-b-x,b+x)=gcd(a-b,b+x),因为b+x为任意值,因此最大的gcd为a-b。操作x次使得(b+x)%(a-b)=0,操作1进行(a-b)-a%(a-b)次或者操作2进行a%(a-b)次,比较大小输出答案。
分类:数学
通过代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll t;
cin>>t;
while(t--){
ll a,b;//记得开long long形
cin>>a>>b;
if(a==b){//注意特例情况
cout<<"0 0"<<endl;
continue;
}
if(b>a)swap(a,b);//注意交换大小
ll ans1=a-b;
ll ans2=min(a%ans1,ans1-a%ans1);
cout<<ans1<<" "<<ans2<<endl;
}
return 0;
}
B题:Customising the Track
题意:给定数组长度n和n个数a[i],你可以任意分配其中的a[i]大小给其他a[j],有值为求和(i=1到N)求和(j=i+1到n)|a[i]-a[j]|,求其最小值
数据范围:多组输入t<1e4,n<2e5,a[i]<1e9,sum n<2e5
样例解释:
输入:
3
3
1 2 3
4
0 1 1 0
10
8 3 6 11 5 2 1 7 10 4
输出:
0
4
21
第一组:最终数组为[2,2,2],答案为0
第三组:数组不变[0,1,1,0],答案为4
第三组为代码验证数据
思路:显然,令a[i]之间尽可能平均,两两相减的绝对值会尽可能小,最终可以使值最小。
分类:思维
通过代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll a[200005];
int main()
{
ll t;
cin>>t;
while(t--){
ll n;
cin>>n;
ll sum1=0,sum0;
for(int i=1;i<=n;i++)cin>>a[i];
for(int i=1;i<=n;i++){
sum1+=a[i];//计算总和
}
sum1=sum1-sum1/n*n;//计算平均化后剩下的差值,即最后留下1的个数
sum0=n-sum1;//最后留下0的个数
cout<<sum1*sum0<<endl;//组合
}
return 0;
}
C题:Need for Pink Slips
题意:给定数据c,m,p,v。每次操作可以选择c,m,p中的一个,如果选择了p则结束选择。
如果选择了c,当c>v时候使c中有v的概率平分给其他有效项,否则讲c平分给其他有效项;选择p同理。
在选择途中,如果某项概率降为0,则变为无效项。
求能参加多少次选择的期望。
数据范围:多组输入t<10,0<c,m,p<1且c+m+p=1,0.1<v<0.9
样例解释:
4
0.2 0.2 0.6 0.2
0.4 0.2 0.4 0.8
0.4998 0.4998 0.0004 0.1666
0.3125 0.6561 0.0314 0.2048
输出:
1.532000000000
1.860000000000
5.005050776521
4.260163673896
第一组:
选择P:0.6;
选择CP:0.2⋅0.7=0.14;
选择CMP:0.2⋅0.3⋅0.9=0.054;
选择CMMP:0.2⋅0.3⋅0.1⋅1=0.006;
选择MP:0.2⋅0.7=0.14;
选择MCP:0.2⋅0.3⋅0.9=0.054;
选择MCCP:0.2⋅0.3⋅0.1⋅1=0.006.
总和=1⋅0.6+2⋅0.14+3⋅0.054+4⋅0.006+2⋅0.14+3⋅0.054+4⋅0.006=1.532
思路:发现每次有三个选择,且P为递归出口,经过若干次选择后,概率最终会积累在P上,最差情况下c=m=0.5,v=0.1大概可以进行20次cmcmcm……cm的选择,约1e6次完全能过。
直接开始dfs,硬搜索。
分类:dfs
通过代码:
#include<bits/stdc++.h>
using namespace std;
double v,res,eps=0.00001;
void dfs(double x,double y,double z,double pro,double deep) {//pro为当前概率,deep为选择次数
//x,y,z为当前dfs的c,m,p概率
if(x>eps) {//如果x还有概率剩余,那就选择x
if(y>eps) { //如果y还有剩余
if(x>=v) dfs(x-v,y+v/2,z+v/2,pro*x,deep+1);//如果比v大,那就把v平分给y和z
else dfs(0,y+x/2,z+x/2,pro*x,deep+1);//如果比v小,那就把x平分给y和z,自己归零
} else {//如果y为无效项
if(x>=v)dfs(x-v,0,z+v,pro*x,deep+1);//如果比v大,那就把v给z
else dfs(0,0,z+x,pro*x,deep+1);//如果比v小,v那就把给z,自己归零
}
}
if(y>eps) {//同理对y操作
if(x>eps) {
if(y>=v)dfs(x+v/2,y-v,z+v/2,pro*y,deep+1);
else dfs(x+y/2,0,z+y/2,pro*y,deep+1);
} else {
if(y>=v)dfs(0,y-v,z+v,pro*y,deep+1);
else dfs(0,0,z+y,pro*y,deep+1);
}
}
//这里对z操作,直接加在答案上
res+=deep*pro*z;//加上现在选择z的概率*之前累计概率*选择次数
}
int main() {
int t;
cin>>t;
while(t--) {
double c,m,p;
cin>>c>>m>>p>>v;
dfs(c,m,p,1,1);//传入当前概率为1,当前选了1个
printf("%.12f\n",res);//直接用cout会输出类似1e-6的答案
res=0;//记得清空
}
return 0;
}
D1题:RPD and Rap Sheet (Easy Version)
题意:交互题,给定n使答案x属于[0,n-1],可询问n次,每次询问后x变为x与询问数异或,猜中成功返回1。
数据范围:多组输入t<1e4,n<2e5,最多询问n次
样例:
样例输入:
1
5 2
0
0
1
样例输出:
3
4
5
思路:考虑x不变的情况下,只需要枚举0到n-1即可,对于若干次询问q[i]来说,答案变为x 异或 q[1] 异或 q[2] 异或 …… 异或 q[i-1]在当前询问只需约去对于非x项,即可完成由0到n-1对x的枚举。因此,对于每次新的询问,都需要异或上一次实际询问的值。
分类:位运算
通过代码:
#include<bits/stdc++.h>
using namespace std;
int q[200005];//下标对应对初始的x进行询问
int main() {
q[0]=0;
for(int i=1; i<200005; i++) {
q[i]=(i-1)^i;//预处理新询问数组
//实际要询问i,但前面询问过i-1,需要约去
}
int t;
cin>>t;
while(t--) {
int n,k,x;
cin>>n>>k;
for(int i=0; i<200005; i++) {
cout<<q[i]<<endl;
cin>>x;
if(x==1)break;
}
}
return 0;
}
D2题:RPD and Rap Sheet (Hard Version)
分类:构造
E1题:Abnormal Permutation Pairs (easy version)
分类:???