7月29日题记 (CF1550C/CF1551D1/CF1551D2/CF1203C/CF1203B)

题目列表

1.CF 1550C
2.CF 1551D1
3.CF 1551D2
4.CF 1203C
5.CF 1203B


1. CF1550C

原题链接

题目大意

求一个数组中满足 (从目标数组里任选三点,满足三个曼哈顿距离没有加减关系) 的连续子区间数量,定义长度为1和2的数组也满足这一条件
good
bad

解题思路

从上面可以知道如果有三个点满足中间的点不被两边的点包含就符合 另外讨论三个以上的点 四个点的时候 可以看成三个点再加上一个点 所以前面三个点是满足关系的 然后我们只要关注最后一个点怎么插
三+一个点

可以看出要满足的话只有边上两个点把中间两个点包起来的时候。四个点以上我就不画了,因为无论如何都是找不到满足这一条件的情况,所以我们就直接暴力枚举首个点 判断后续长度为3和4子区间是否满足这一条件即可。

AC代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+10;
int d[maxn];
int main(){
	int t,n,tmp,i,j,k,ans;
	scanf("%d",&t);
	while(t--){
		scanf("%d",&n);
		ans=2*n-1;
		for(i=0;i<n;i++){
			scanf("%d",&d[i]);
		}
		for(i=0;i<n-3;i++){
			if((d[i+1]>d[i]&&d[i+1]>d[i+2])||(d[i+1]<d[i]&&d[i+1]<d[i+2])){
				ans++;
				if( ((d[i+3]<d[i+1]&&d[i+3]>d[i+2])||(d[i+3]>d[i+1]&&d[i+3]<d[i+2])) && ((d[i]<d[i+1]&&d[i]>d[i+2])||(d[i]>d[i+1]&&d[i]<d[i+2])) )
					ans++;
			}
		}
		if(n>=3){
			if((d[n-2]>d[n-3]&&d[n-2]>d[n-1])||(d[n-2]<d[n-3]&&d[n-2]<d[n-1]))
				ans++;
		}
		printf("%d\n",ans);
	}
	return 0;
}

2. CF1551D1

原题链接

题目大意

在NxM的棋盘上摆1x2的多米诺骨牌,判断是否能在摆下k的水平块的前提下摆满整个棋盘

解题思路

刚刚开始的思路是用某些小块固定出大块,然后发现思路不对,很难考虑完全。然后我就去看官方题解了…
题解的大致意思是按n和m的奇偶分成四种情况

  1. n奇m奇:不用考虑,肯定是不可能。
  2. n偶m偶:k不会超过 m * n / 2 所以肯定可以做到。
  3. n偶m奇:既然n偶m偶能过,那就想办法让m的一行填掉。
  4. n奇m偶:原理同上,看看能不能填掉n的一行。
AC代码
#include<bits/stdc++.h>
using namespace std;
int main(){
	int t;
	scanf("%d",&t);
	int n,m,k;
	int kk;
	while(t--){
		scanf("%d%d%d",&n,&m,&k);
		kk=n*m/2-k;
		if(n%2&&m%2){
			printf("NO\n");
			continue;
		}
		else if(n%2){
			k-=m/2;
		}
		else if(m%2){
			kk-=n/2;
		}
		if(k<0||k%2||kk<0){
			printf("NO\n");
			continue;
		}
		printf("YES\n");
	}
	return 0;
}

3 . CF1551D2

原题链接

题目大意

上一道题目的构造版本。

解题思路

思路和上面以提是一样的,但是构造思路很麻烦,看代码吧,以为涉及到字符串,所以用了我比较熟悉的python写,写的是十分的冗长…

AC代码
t=int(input())
h1="ac"
h2="bd"
s1="ef"
s2="gh"
for aslkfjalkfj in range(t):
	n,m,k=[int(i) for i in input().split()]
	kk=n*m//2-k
	if(n%2 and m%2):
		print("NO")
		continue
	elif n%2:
		k-=m//2
	elif m%2:
		kk-=n/2
	if(k<0 or k%2 or kk<0):
		print("NO")
		continue
	print("YES")
	mp=['']*n
	x=0
	y=0
	tmp=0
	if(n%2):
		while k>0:
			mp[y]+=h1[tmp]+h1[tmp]
			mp[y+1]+=h2[tmp]+h2[tmp]
			tmp=1-tmp
			x+=2
			k-=2
			if(x==m):
				x=0
				y+=2
		while kk>0:
			if y>0:
				if mp[y-1][x]==s1[tmp]:
					tmp=1-tmp
			mp[y]+=s1[tmp]+s2[tmp]
			mp[y+1]+=s1[tmp]+s2[tmp]
			tmp=1-tmp
			x+=2
			kk-=2
			if(x==m):
				x=0
				y+=2
		mp[n-1]='xxyy'*(m//4)+'x'*(m%4)
	if(m%2):
		while k>0:
			mp[y]+=h1[tmp]+h1[tmp]
			mp[y+1]+=h2[tmp]+h2[tmp]
			tmp=1-tmp
			x+=2
			k-=2
			if(x==m-1):
				x=0
				y+=2
		while kk>0:
			if y>0:
				if mp[y-1][x]==s1[tmp]:
					tmp=1-tmp
			mp[y]+=s1[tmp]+s2[tmp]
			mp[y+1]+=s1[tmp]+s2[tmp]
			tmp=1-tmp
			x+=2
			kk-=2
			if(x==m-1):
				x=0
				y+=2
		x="xy"
		for i in range(0,n,2):
			mp[i]+=x[tmp]
			mp[i+1]+=x[tmp]
			tmp=1-tmp
	else:
		while k>0:
			mp[y]+=h1[tmp]+h1[tmp]
			mp[y+1]+=h2[tmp]+h2[tmp]
			tmp=1-tmp
			x+=2
			k-=2
			if(x==m):
				x=0
				y+=2
		while kk>0:
			if y>0:
				if mp[y-1][x]==s1[tmp]:
					tmp=1-tmp
			mp[y]+=s1[tmp]+s2[tmp]
			mp[y+1]+=s1[tmp]+s2[tmp]
			tmp=1-tmp
			x+=2
			kk-=2
			if(x==m):
				x=0
				y+=2
	for i in mp:
		print(i)

4. CF 1203C

原题链接

题目大意

找到输入n个数的最大公因子,再求出这个公因子又几个因数

解题思路

div3水题,连续gcd就可以求出最大公因子 然后因数分解只需要用试除法即可 时间复杂度是够的(不会分析gcd的时间复杂度

AC代码
#include<bits/stdc++.h>
using namespace std;
long long gcd(long long a,long long b){
	return b==0?a:gcd(b,a%b);
}
int main(){
	int n;
	scanf("%d",&n);
	long long i,j,k;
	long long tmp,igcd;
	scanf("%lld",&igcd);
	for(i=1;i<n;i++){
		scanf("%lld",&tmp);
		igcd=gcd(igcd,tmp);
	}
	long long ans=0;
	// qiu igcd de yin shu
	for(i=1;i<=sqrt(igcd);i++){
		if(igcd%i==0){
			ans+=2;
			if(i*i==igcd)
				ans--;
		}
	}
	printf("%lld",ans);
	return 0;
}

5. CF 1203B

原题链接

题目大意

给一组边,判断是否能用所给边构造出的所有矩形面积相等。

解题思路

贪心,要想所有矩形面积相等,必须从最长和最短边里选

AC代码
#include<bits/stdc++.h>
using namespace std;
map<int,int>mp;
struct node{
	int val,num;
};
vector<node>vtmp;
int main(){
	int t;
	scanf("%d",&t);
	int n,i,j,k,tmp,flag;
	while(t--){
		mp.clear();
		vtmp.clear();
		scanf("%d",&n);
		for(i=0;i<4*n;i++){
			scanf("%d",&tmp);
			mp[tmp]++;
		}
		flag=1;
		for(map<int,int>::iterator it=mp.begin();it!=mp.end();it++){
			if(it->second%2){
				flag=0;
				printf("NO\n");
				break;
			}
			vtmp.push_back({it->first,it->second});
		}
		if(flag){
			int S=vtmp[0].val*vtmp[vtmp.size()-1].val;
			if(vtmp[0].num!=vtmp[vtmp.size()-1].num){
				printf("NO\n");
				continue;
			}
			for(i=1,j=vtmp.size()-2;i<=j;i++,j--){
				if(vtmp[i].val*vtmp[j].val!=S){
					printf("NO\n");
					flag=0;
					break;
				}
				if(vtmp[i].num!=vtmp[j].num){
					printf("NO\n");
					flag=0;
					break;
				}
			}
			if(flag)
				printf("YES\n");
		}
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

我爱碎龙 碎龙爱我

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值