2.NOIP模拟赛试题详讲

本文详细讲解了NOIP模拟赛中的三道题目,涉及棋子移动策略、01串翻转最小代价和图论问题。通过案例分析,解释了如何运用全排列、差分思想和最短路径算法解决这些问题,并提供了部分代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

A

题目描述:数轴上有n个棋子, 第i 个棋子初始在ai.你会不断对棋子进行操作, 每次操作是选择一个棋子, 假设它的坐标是x, 则可以把它移动到x−1或x−2, 但要求移动后的位置原先没有棋子.如果一个棋子的坐标变得小于等于0, 则称它挂掉了. 你需要求出有多少个排列p使得存在一种方案使得第i 个挂掉的棋子是pi. 答案对109+ 7取模.

解析
1.假如两个棋子位于101,103,和两个棋子位于1,3是没有区别的,可以101先挂掉,也可以以103先挂掉。
2.假如位于2,3,4,那么2,3就会堵住4,所以2,3必须挂掉一个。
3.假如位于1,3,5,那么3个数都可以畅通无阻,排列方式就是全排列 n ! n! n!(排列数公式)。

我们分析了以上3种情况,那么我们考虑维护一个序列1,3,5,7,…,2i-1,如果a[i]==2i,那么我们要将前面的一个挂掉,序列保持不变,如果a[i]>=2i-1,那么统计方案数。

for(int i=1;i<=n;i++)
{
   
	ans=ans*i%mod;
}

求全排列,直接累乘。

#include<bits/stdc++.h>
using namespace std;
#define ll long long 

const int mod=1e9+7;
int n,a[100005];

int main()
{
   
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
		scanf("%d",&a[i]);
	ll ans=1;
	vector<int>b(1,1);//表示向量[1]==1
	for(int i=2;i<=n;i++)
	{
   
		if(a[i]!=b.back()+1)//不在2*i的位置
		{
   
			b.push_back(b.back()+2);
		}
		else//在的话,那么挂掉前面的一个,至于哪一个,都可以
		{
   
			ans=ans*(b.size()+1)%mod;
		}
	}
	for(int i=1;i<=b.size();i++)
	{
   
		ans=ans*i%mod;
	}
	cout<<ans;
	return 0;
}

B

题目描述:有一个长度为a+b+c+d+e的01串, 它由a个1, b个0, c个1, d个0, e个1拼接起来组成.有m个区间[li,ri]. 你可以进行若干次操作, 每次操作选择一个区间[li,ri] 并将[li,ri] 取反, 花费的代价为ri −li+ 1.求将这个串变成全1串的最小代价. 无解输出−1.

解析
它是有5个区间组成,要将所有01串的都翻转太复杂了,不妨差分的思想,表示该位置和下一个位置的数字是否相同,相同为0,不同为1。例如a,b,c,d,e分别等于1,2,3,4,5。即100111000011111,差分后为101001000100000,对应了下标a,a+b,a+b+c,a+b+c+d。
重点: 如果我们要全部为1,即把差分的变成000000000000…,所以要让差分01串中的第1到第2的最短+第3到第4的最短,或者第1到第3+第2到第4,或者第1到第4+第2到第3,咦?这不就有点像最短路问题了吗,那就用这个思路,将这4个1作为点,每个取反的区间[l,r]为边,表示从l-1到r边权为r-l+1的边,来建立无向图,跑3遍dijstrar就解决了问题。
所以问题就转换到图上了 (太妙了)

#include<bits/stdc++.h>
using namespace std;

#define num ch-'0'
void get(int &res)
{
   
    char ch;bool flag=0;
    while(!isdigit(ch=getchar()))
        (ch=='-')&&(flag=true);
    for(res=num;isdigit(ch=getchar
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值