[思维题][校内模拟] 201028 NOIP T1

T1 A

题意

给出一些棋子的位置,对于每一个棋子,可以左移一格或两格,前提是目标位置上无棋子
移出棋盘(即坐标 ≤ 0 \le 0 0)则记为挂掉,问挂掉的顺序有多少种

正解

观察发现有如下的情况,棋子挂掉的顺序是任意的

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2m2WJ5X3-1603874684272)(C:\Users\am\AppData\Roaming\Typora\typora-user-images\image-20201028162744488.png)]

考虑目前棋子坐标 1 , 3 , 5 , ⋯   , ( 2 i − 1 ) 1,3,5,\cdots,(2i-1) 1,3,5,,(2i1),共 i i i个,加入棋子
如果加入到 2 i 2i 2i,必须挂掉一个才能维护上述形态, a n s × ( i + 1 ) ans\times (i+1) ans×(i+1)
如果加入到 ≥ 2 i + 1 \ge 2i+1 2i+1,可以得到上述形态

然后开个数组维护就好了
优美,极简,是我心中代码的样子

#include<bits/stdc++.h>
using namespace std;
#define in Read()
int in{
	int i=0,f=1;char ch=0;
	while(!isdigit(ch)&&ch!='-') ch=getchar();
	if(ch=='-') ch=getchar(),f=-1;
	while(isdigit(ch)) i=(i<<3)+(i<<1)+ch-48,ch=getchar();
	return i*f;
}

const int mod=1e9+7,N=2e5+5;
int n,a[N],cnt,ans=1,sta[N];

int mul(int a,int b){return 1ll*a*b%mod;}

int main(){
	n=in;
	for(int i=1;i<=n;++i) a[i]=in;
	sort(a+1,a+n+1);
	for(int i=1;i<=n;++i){
		if(a[i]==cnt*2) ans=mul(ans,cnt+1);
		else sta[++cnt]=cnt*2-1;
	}
	while(cnt){
		ans=mul(ans,cnt);
		--cnt;
	}
	printf("%d\n",ans);
	return 0;
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值