程序设计思维与实践 CSP-M4 补题

题目

题意

在这里插入图片描述

做法

开一个10位数组,分别记录有几个不同个数。
及时break。
注意不关同步超时。
时间复杂度大概在O(位数*n);

代码

#include<iostream>
#include<string>
#include<string.h>
using namespace std;

int a[11];

int main()
{	ios::sync_with_stdio(false);
	int n,k,ans=0;
	cin>>n>>k;
	
	for(int i=0; i<n; i++)
	{
		memset(a,0,sizeof(a));
		string temp;
		cin>>temp;
		int num=0;
		for(int j=0; j<temp.size(); j++)
		{
			int t=temp[j]-'0';
			if(a[t]==0)
			{
				a[t]=1;
				num++;
			}
		}
		if(num < k)
		    ans++;
	}
	cout<<ans<<endl;
 } 

题目

题意

在这里插入图片描述

做法

由于数据量小,直接枚举所有点作为圆心,然后记录与其他点的距离作为半径(找到最长的)即可。
考试的时候由于没有看见圆心在发射点上,导致花了很长时间写最小圆覆盖(orz)

代码

#include<iostream>
#include<cmath>
using namespace std;
const int N=1005;
int n;
const double inf=1e11;
struct node
{
	double x,y;
	bool operator<(const node &p)const
	{
		if(x!=p.x)return x<p.x;
		if(y<p.y)return y<p.y;
	}
	bool operator ==(const node &p)const
	{
		if(x==p.x&&y==p.y)return true;
		else return false;
	}
}a[N];
double r=inf;
node o;
double get_r(node &a,node&b)
{
	return pow(a.x-b.x,2)+pow(a.y-b.y,2);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)scanf("%lf%lf",&a[i].x,&a[i].y);
	for(int i=1;i<=n;i++)
	{
		node oo=a[i];
		double rr=0;
		for(int j=1;j<=n;j++)rr=max(get_r(oo,a[j]),rr);
		if(rr<r)
		{
			o=oo;
			r=rr;
		}
		else if(rr==r)
		{
			if(oo.x<o.x)o=oo;
			else if(oo.x==o.x&&oo.y<o.y)o=oo;
		}
	}
	printf("%.2lf %.2lf\n",o.x,o.y);
	printf("%.2lf\n",r);
} 

题目

题意

在这里插入图片描述

做法

注意到本题是一个二叉搜索树,也就是说对于任意一点,比他小的在左子树上,比他大的在右子树上。
也就是说中序遍历的时候是从小到大的。
首先用一个f数组,记录一下哪两个点可以连边。
(通过最大公约数。)
不妨设置两个数组。
L[i,j]表示区间[i,j-1]作为其左儿子是否合法。
R[i,j]表示区间[i+1,j]作为j的右儿子是否合法。
则接下来转移即可如下:
对于[l,r]其中的k。
若满足L[l][k]和R[k][r]均合法,则
若l和r恰好是边界1,n,则正退出输出。
判断l-1是否能和k相连,若能则R[l-1][r]置为1;
同理判断r+1;
全部遍历完毕后,判断是否有符合题意的情况即可。

代码

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int N=800;
int t;
int n,a[N],f[N][N],L[N][N],R[N][N];
int bj=0;
int main()
{
  ios::sync_with_stdio(false);
  cin>>t;
	while(t--)
	{	bj=0;
		memset(L,0,sizeof(L));
 	 	memset(R,0,sizeof(R));
  		memset(f,0,sizeof(f));
	  	cin>>n;
  		for(int i=1;i<=n;i++) cin>>a[i],L[i][i]=R[i][i]=1;
  		for(int i=1;i<=n;i++) 
  		for(int j=1;j<=n;j++)
   		if(__gcd(a[i],a[j])>1) f[i][j]=f[j][i]=1;
  		for(int l=n;l>=1;l--)
		for(int r=l;r<=n;r++)
		for(int k=l;k<=r;k++)
    	if(L[l][k]&&R[k][r])
      	{
			if(l==1&&r==n) {bj=1;}
			if(f[l-1][k]) R[l-1][r]=1;
			if(f[k][r+1]) L[l][r+1]=1;
      	}
      	if(bj==1)printf("Yes\n");
      	else 
  		printf("No\n");
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值