Codeforces Round #499 (Div. 2) D E

14 篇文章 0 订阅
3 篇文章 0 订阅

题目链接

D. Rocket

题意:

一道交互题,要求在询问不超过 60 60 60 次求出一个 x x x 的值,其中 ( 1 < = x < = m ) (1<=x<=m) (1<=x<=m) 每次询问如果大于 x x x 就返回 − 1 -1 1 ,小于 x x x 就返回 1 1 1 ,等于就结束程序,但是回答不一定是真的,有一个 01 01 01 序列 p p p ,根据序列,第一次询问就看 p [ 1 ] p[1] p[1] ,如果为1那么回答为真,否则回答为相反数。不知道 p p p 序列,但知道其长度, l e n p < = 30 len_p<=30 lenp<=30 , p p p 序列是循环的,即第 l e n p + 1 len_p+1 lenp+1 次询问看 p [ 1 ] p[1] p[1]

思路:

由于可以询问 60 60 60 次,那么我们先用一半的次数,求出 p p p 序列,然后就是一个简单的二分了。求 p p p 序列可以用一个最小的值来试,返回 − 1 -1 1 必然为假话。

代码:

#include <bits/stdc++.h>
using namespace std;
int out(int x){
	cout<<x<<endl;
	int t;
	cin>>t;
	fflush(stdout);
	return t;
}
int n,m;
int bj[60];
int main()
{
	cin>>m>>n;
	for(int i=0;i<n;i++){
		int t=out(1);
		if(t==0){
			return 0;
		}else if(t==-1){
			bj[i]=1;
		}
	}
	int l=2,r=m,cs=0;
	while(l<=r){
		int mid=(l+r)/2;
		int t=out(mid);
		if(t==-2){
			return 0;
		}
		if(bj[cs])t=-t;
		if(t==0){
			return 0;
		}else if(t==1){
			l=mid+1;
		}else r=mid-1;
		cs=(cs+1)%n;
	}
	return 0;
}

E. Border

题意:

n n n种币值(十进制),每种有无数张,现在要求出这些币值可以构成的币值在 k k k 进制下的个位数有多少种?依次输出

思路:

首先分析只有每个币值在 k k k 进制下的个位数起作用,将每个数 m o d k modk modk a [ 1 ] ∗ k 1 + a [ 2 ] ∗ k 2 + . . . . + a [ n ] ∗ k n = m ( m o d k ) a[1]*k_1+a[2]*k_2+....+a[n]*k_n=m (mod k) a[1]k1+a[2]k2+....+a[n]kn=m(modk)
根据裴蜀定理, g c d ( a [ 1 ] , a [ 2 ] , . . . a [ n ] ) ∣ m gcd(a[1],a[2],...a[n])|m gcd(a[1],a[2],...a[n])m ,那么我们求他们的公约数,不断地做 m o d k modk modk 加法,出现地余数就是所求的。

代码:

#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int gcd(int a,int b){
	return b==0?a:gcd(b,a%b);
}
int a[N];
int n,k;
int ans[N];
int main()
{
	scanf("%d%d",&n,&k);int t=0;
	for(int i=1;i<=n;i++){
		scanf("%d",&a[i]);
		t=gcd(t,a[i]);//公约数
	}
	//cout<<t<<endl;
	int v=t%k;
	while(1){
		if(ans[v])break;//出现循环节
		ans[v]=1;v=(v+t)%k;//不能加v
	}
	int sum=0;
	for(int i=0;i<k;i++)if(ans[i])sum++;
	printf("%d\n",sum);
	for(int i=0;i<k;i++)if(ans[i])printf("%d ",i);puts("");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值