20211012NOIP模拟赛
非常抱歉,没有题面;
简单总结:
第一题打表22分,第二题2分,第三题特判29分;总分数53分;
一如既往的菜~~~
1.A。
思路:用一个栈来存储数据;
如果两个数之间有空位,就放在栈的最后一位+2上,入栈;
如果没有,ans*=栈的大小+1,为什么呢?因为前size+1个数每一个数都可以先出战,所以是size+1,该元素不入栈;
处理完后:站内的元素想怎么出栈都可以所以是阶乘;
1 #include<bits/stdc++.h> 2 using namespace std; 3 inline long long read(){ 4 static char ch; 5 long long res=0; 6 long long sign=1; 7 while((ch=getchar())<'0'||ch>'9'){ 8 if(ch=='-'){ 9 sign=-1; 10 } 11 } 12 res=ch-'0'; 13 while((ch=getchar())>='0'&&ch<='9'){ 14 res=res*10+ch-'0'; 15 } 16 return res*sign; 17 } 18 const long long P=1e9+7; 19 int n; 20 int main(){ 21 cin>>n; 22 vector<int> a(n); 23 for(int i=0;i<n;i++){ 24 cin>>a[i]; 25 } 26 vector<int > b(1,1); 27 long long ans=1; 28 for(int i=1;i<n;i++){ 29 if(a[i]!=b.back()+1){ 30 b.push_back(b.back()+2); 31 }else{ 32 ans=(long long)ans*(b.size()+1)%P;//该元素在前b.size个元素中的出战顺序,首尾加上中间的间隔随便排 33 } 34 } 35 for(int i=0;i<(int)b.size();i++){ 36 ans=ans*(long long)(i+1)%P;//剩下的元素出战顺序随意 37 } 38 printf("%lld\n",ans); 39 40 return 0; 41 }
2.
用最短路我着实没有想到;
用一个差分数组记录每一个分界点的位置,
每一次改变都连一条边,每个分界点跑一次最短路,然后找出两两相加的最小值


浙公网安备 33010602011771号