csp4模拟总结

在这里插入图片描述

解题思路:

这个题目整体上还是比较简单的,但是注意点相对来讲也是比较多,自己写的时候时间超时了,自己运用了STL中的map,相对数组来讲,map的维护还是比较耗时的。通过这个题目,感觉自己感触最深的一点便是写代码要有一点的洁癖,追求最优最简,以防不经意间的时间超时或是空间超时。比如对于本题目而言,对于字符串的处理既可以进行全部存储,也可以便输入便计算,而通过实际验证,进行二维字符串的存储会时间超时,在数据量极大的情况下,一些操作细节也会决定程序的正确与否。另外,试了一下如果是关同步情况下,耗时更小一些,对于这些,我们要有一定的意识。

代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int n,k;
char s[18];
bool label[10]={0};
int cc;
int ans=0;
int main()
{
	scanf("%d%d",&n,&k);
	if(k>10)
	{
		cout<<n<<endl;
		return 0;
	}
	for(int i=0;i<n;i++)
	{
		scanf("%s",s);
	               int sz=strlen(s);
		memset(label,0,sizeof(label));
		cc=0;
		for(int j=0;j<sz;j++)
		{
			if(label[s[j]-'0']==0)
			{
				label[s[j]-'0']=1;
				cc++;
				if(cc>=10)
				break;
			}
		}
		if(cc<k)
		ans++;
	}
	printf("%d\n",ans);
	}在这里插入代码片

在这里插入图片描述

解题思路:

对于这道题,自己完全错掉了,这个确实是不应该的,不过也好,学到了一些东西。对于做题尤其是在读题环节千万不能够想当然,题目读不准,便不能写程序。对题意的检查远远强于对程序的检查。反映到这道题目上,便是对于半径的平方的说明,这是题目中明确说明的,也不知道怎么就稀里糊涂的略过去了。另外我们要对double进行重认识,该类型的精确位数是有限的,在整数方面较于long long优先级我们需要选择后者。关于这个题目,思路方面比较简单,详细看代码。

代码:

#include<iostream>
#include<stdio.h>
#include<cmath>
#include<algorithm>
using namespace std;
long long n;
long long locx[1005];
long long locy[1005];
long long ter=0;
long long r=100000000000000;
long long x,y;
int main()
{
	scanf("%lld",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%lld%lld",&locx[i],&locy[i]);
	}
	x=locx[1],y=locy[1];
	for(int i=1;i<=n;i++)
	{
		ter=0;
		for(int j=1;j<=n;j++)
		{
			ter=max(ter,((locx[j]-locx[i])*(locx[j]-locx[i])+(locy[j]-locy[i])*(locy[j]-locy[i])));		
		}
		if(r==ter&&((locx[i]==x&&locy[i]<y)||(locx[i]<x)))
		{
			x=locx[i],y=locy[i];
		}
		else if(ter<r)
		{
			r=ter;
			x=locx[i],y=locy[i];
		}
	}
	printf("%lld.00 %lld.00\n",x,y);
	printf("%lld.00\n",r);
}在这里插入代码片

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

解题思路:

对于这道题目,感觉难度比较大,自己在模拟期间思考了一个小时左右,但是没出一点思路。挫败感足足的。完成这道题目,大约需要分四步.1,确定动态规划的方向去解题。2.定出状态,3.状态转移.4.程序优化。回顾了一下自己做题时的过程,准确地讲自己在第一步确定动态规划的方向时尚且有点犹豫,第二步便直接垮掉了。所以讲还是学到了新东西的,不过,自己水平确实有些浅。
仔细想了一下,感觉问题还是出在自己对于二叉搜索树的理解不够深,本质性的东西不敏感。另一方面,应该还是做题量比较少,所以那种灵活的反射性思维不足。对于二叉搜索树,其本质在于递归分二叉,特点在于根节点大于左子树,小于右子树。而本质与特点正说明了定状态,状态转移两部分如何构造。感觉在dp问题面前,一些没有逻辑的思考往往时混乱的,而这种思考要求确实比较高。对树结构而言,我们惯性的思维喜欢从上往下进行思考,而对于本道题,我们是要还原树,所以一种从上往下的思考是不可行的(或是不易行的),我们采取逐渐累积,逐渐构造的形式对整棵树进行还原,这样在dp的解法中才有踪迹可寻。所以状态的定取目的在于合叉,合叉的原则与形式为二叉搜索树的特性。在这里,我们比较清楚的感受到确定“根节点”的意识在树结构的dp中的重要性,这是寻找子问题的关键因素。另一方面,题目中直接给出了有序的数组,这一点有些暗示作用,起码有序数组的子结构很明显是有序的。整体来讲,这道题目利用的时区间dp进行求解,区间dp通常是三重循环,这道题目也一样,第三重循环需要进行枚举。另外一个注意点,在状态更新时,有时解法是利用上一区间更新当前区间状态,有时是利用当前区间更新下一区间的状态,这跟具体思路有关。另外便是复杂度方面,对于两个点公约数是否大于一,在程序中或许需要多次使用,所以我们一次性将其算出并存储下来,否则会超时。
最后,题目给出的gcd算法很优秀,非常简洁,建议背记下来。

代码:

#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;
int gcd(int a,int b) {
	return b==0?a:gcd(b,a%b);
}
int t,n;
long long func[705];
bool le[705][705];
bool rig[705][705];
bool fun[705][705];
bool label;
int main() {
	scanf("%d",&t);
	while(t--) {
		scanf("%d",&n);
		label=0;
		memset(func,0,sizeof(func));
		memset(le,0,sizeof(le));
		memset(rig,0,sizeof(rig));
		memset(fun,0,sizeof(fun));
		for(int i=1; i<=n; i++) {
			scanf("%lld",&func[i]);
		}
		for(int i=1;i<=n;i++)
		{
			for(int j=i;j<=n;j++)
			{
				if(gcd(func[i],func[j])>1)
				{
					fun[j][i]=1;
					fun[i][j]=1;
				}
			}
	    }
		if(func[1]<=0) {
			printf("No\n");
		} else {
			for(int i=1; i<=n; i++)
				le[i][i]=1,rig[i][i]=1;
			for(int i=1; i<=n; i++) {
				for(int j=1; j<=n-i+1; j++) {
					for(int k=j; k<=j+i-1; k++) {
						if(le[j][k]&&rig[k][j+i-1]&&j-1>=1&&fun[k][j-1])
							rig[j-1][j+i-1]=1;
						if(le[j][k]&&rig[k][j+i-1]&&j+i<=n&&fun[k][j+i])
							le[j][j+i]=1;
					}
				}
			}
			for(int i=1; i<=n; i++) {
				if(le[1][i]&&rig[i][n]) {
					label=1;
					break;
				}
			}
			if(label==1)
				printf("Yes\n");
			else
				printf("No\n");
		}
	}
}在这里插入代码片
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值