Codeforces Round #499 (Div. 2) D E

題目鏈接

D. Rocket

題意:

一道交互題,要求在詢問不超過 6060 次求出一個 xx 的值,其中(1<=x<=m)(1<=x<=m) 每次詢問如果大於 xx 就返回 1-1 ,小於 xx 就返回 11 ,等於就結束程序,但是回答不一定是真的,有一個 0101 序列 pp ,根據序列,第一次詢問就看 p[1]p[1] ,如果爲1那麼回答爲真,否則回答爲相反數。不知道 pp 序列,但知道其長度,lenp<=30len_p<=30 , pp 序列是循環的,即第 lenp+1len_p+1 次詢問看 p[1]p[1]

思路:

由於可以詢問 6060 次,那麼我們先用一半的次數,求出 pp 序列,然後就是一個簡單的二分了。求 pp 序列可以用一個最小的值來試,返回 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

題意:

nn種幣值(十進制),每種有無數張,現在要求出這些幣值可以構成的幣值在 kk 進制下的個位數有多少種?依次輸出

思路:

首先分析只有每個幣值在 kk 進制下的個位數起作用,將每個數 modkmodka[1]k1+a[2]k2+....+a[n]kn=m(modk)a[1]*k_1+a[2]*k_2+....+a[n]*k_n=m (mod k)
根據裴蜀定理,gcd(a[1],a[2],...a[n])mgcd(a[1],a[2],...a[n])|m ,那麼我們求他們的公約數,不斷地做 modkmodk 加法,出現地餘數就是所求的。

代碼:

#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("");
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章