Good Bye 2023 A-D(E代补)

比赛链接

这场是vp选手。

A.2023(模拟)

题意:有一个长度为(n+k)的数组a,删去k个元素后,得到数组b,你需要判断能否得到一个数组a,使其各项的乘积是2023。直接模拟即可,记得开long long

#include<iostream>
#include<vector>
#define int long long 
using namespace std;
const int N=2e5+10;
int T,n,k;
void solve(){
	int ans=1;
	cin>>n>>k;
	for(int i=1;i<=n;i++){
		int x;
		cin>>x;
		ans*=x;
	}
	if(2023%ans!=0||ans>2023){
		cout<<"No"<<endl;
		return;
	}
	cout<<"Yes"<<endl;
	k--;
	cout<<(2023/ans)<<' ';
	while(k--){
		cout<<1<<' ';
	}
	cout<<endl;
}
signed main(){
	cin>>T;
	while(T--){
		solve();
	}
}

B.Two Divisons(数学,找规律)

题意,给定两个数字,a,b,找到x。使得x是a,b的最大除数。

设a=\frac{x}{p},b=\frac{x}{q},假定a<b

若a|b时,x=bq=\frac{b{_{}}^{2}}{a}

否则x=lcm(a,b)

#include<iostream>
#define int long long 
using namespace std;
const int N=2e5+10;
int T,n;
int gcd(int a,int b){
	if(b==0)return a;
	return gcd(b,a%b);
}
void solve(){
	int a,b;
	cin>>a>>b;
	int d=gcd(a,b);
	if(a>b)swap(a,b);
	//if(a==1)cout<<b*b<<endl;
	if(b%a==0)cout<<b*b/a<<endl;
	else cout<<a/d*b<<endl;
	return;
}
signed main(){
	cin>>T;
	while(T--){
		solve();
	}
}

C.Training Before the Olympiad(思维)

给定一个长度为n的序列,每次进行一次操作,将两个数加起来向下取整后再乘二,即:(a_i{+}a_j{})/2*2,然后把这个数加进序列,直到只剩两个数的时候,结束游戏。

小A的目的是让当前最后剩的数尽量大,小B的目的想让当前剩下的数尽可能的小。问你前k个数最后得到的数是多少。

首先我们发现,前k个数可以进行的操作是k-1次,所以前两个数最终的答案序列是确定的。

然后:我们发现答案肯定是不会变大,只会变小的,奇+偶会让答案减少1。不难发现,小A会把两个奇数变成一个偶数,小B会让一个 奇数+一个偶数变成一个偶数,这样会让答案减少1,所以我们只要考虑前k个数的奇数的个数就行了

#include<iostream>
#define int long long 
using namespace std;
const int N=2e5+10;
int T,n,a[N],dp[N],ans[N];
void solve(){
	cin>>n;
	int cnt=0;
	int sum=0;
	for(int i=1;i<=n;i++)cin>>a[i];
	if(n==1){
		cout<<a[1]<<endl;
		return;
	}
	if(n==2){
		cout<<a[1]<<' '<<((a[1]+a[2])/2*2)<<endl;
		return;
	}
	ans[1]=a[1];
	ans[2]=(a[1]+a[2])/2*2;
	int tag=1;//记录当前是谁行动 
	for(int i=1;i<=n;i++){
		int x=a[i];
		sum+=x;
		cnt+=(x&1);
		if(i<3)continue;
		int res=sum;
		res-=cnt/3;
		if(cnt%3==1)res--;
		ans[i]=res;
	}
	for(int i=1;i<=n;i++)cout<<ans[i]<<' ';
	cout<<endl;
}
signed main(){
	cin>>T;
	while(T--){
		solve();
	}
}

D.Mathematical Problem(找规律,数学)

题意,找一个长度为n的n个平方数,这n个数数字出现的个数种数必须完全相同。n为奇数。

n=3的时候 169,196,961。

n=5的时候,可以有16900,19600,96100…… 但仅仅如此吗?

我们发现,往1 xxxx 6 xxxx 9 中间插入若干个相等数量的0,最终是不会影响结果的。

假设往中间插入了x个0。

那么这个数sum=(10^{2x+2}+6*10^{x+1}+9),可以一眼看出这个数是一个完全平方,开根号就是10^{x+1}+3,如果位数不够往后面补若干个0就行,可以发现,插入x个0后,一共有2x+3位,一定是奇数,往后插入偶数个0,不会改变其完全平方的性质。

9xxxx6xxxx1同理

我们发现上面两种情况加起来一共有n/2*2种,即(n-1)种,最后一种169+0000000即可。

#include<iostream>
#include<cmath>
#include<map>
#define endl '\n'
using namespace std;
const int N=2e5+10;
int T,n,a[N];
void check(){
	int cnt=0;
	for(int i=10000;i<=99999;i++){
		int x=i;
		int flag=1;
		int t=sqrt(i);
		if(t*t==i)cout<<i<<endl;
	}
}
void solve(){
	cin>>n;
	if(n==1){
		cout<<1<<endl;
		return;
	}
	if(n==3){
		cout<<169<<endl;
		cout<<196<<endl;
		cout<<961<<endl;
	}
	else{
		//1 6 9中间可以插任意个0
		//两种情况恰好是n/2个,所以最后差一个 
		for(int i=1;i<n;i+=2){ 
			int now=3;
			cout<<9;
			for(int j=1;j<=i/2;j++){
				cout<<0;
				++now;
			}
			cout<<6;
			for(int j=1;j<=i/2;j++){
				cout<<0;
				++now;
			}
			cout<<1;
			for(int j=now;j<n;j++)cout<<0;
			cout<<endl;
		} 
		for(int i=1;i<n;i+=2){ 
			int now=3;
			cout<<1;
			for(int j=1;j<=i/2;j++){
				cout<<0;
				++now;
			}
			cout<<6;
			for(int j=1;j<=i/2;j++){
				cout<<0;
				++now;
			}
			cout<<9;
			for(int j=now;j<n;j++)cout<<0;
			cout<<endl;
		}
		//少一个
		cout<<196;
		for(int i=3;i<n;i++)cout<<0;
		cout<<endl; 
	}
}
int main(){
	//check();
	cin>>T;
	while(T--){
		solve();
	}
}

------------------------------------------------------------The End----------------------------------------------------------------------------

  • 8
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值