AtCoder 2316 思维题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了AtCoder 2316 思维题相关的知识,希望对你有一定的参考价值。
题目链接:https://vjudge.net/problem/AtCoder-2316
题意:给你n个人的位置,每个人能往左跳一格或两格到无人的位置,跳到0位置,这个人消失。n个人消失组成一个排列,问有多少种排列。
感觉自己题目做得少也不是很聪明,这种手推规律或者说考验思维的题目还是很头疼啊。
最后看了zzh大佬非常简短的AC代码,又问了队友之后才终于懂了一丢丢,但是以后遇到怕是还是不会。
如果人是一个隔一个站的,也就是站在1 3 5 7 9...的位子上,那n个人就有 n! 种排列。
如果不是这种情况,那我们就要让其中一些人先出去来维持这样的情况。那么如何维持呢?
比如现在情况是1 3 4 5,那我们要让前面三个人中出去一个,有三种情况,然后其他三个人就有 3! 种情况。
所以总结一下就是,先定义ans = 1, k = 0表示现在队列里的人数。
依次读入人的位置,k++,直到有人不符合1 3 5 7...的情况,就ans *= k,然后k--。
这样就一直维持了1 3 5 7...这个状态,最后ans再乘k的阶乘就行啦。
最后要注意ans要用long long, 每步都要MOD。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #include<vector> 7 #include<set> 8 #include<string> 9 #include<sstream> 10 #include<cctype> 11 #include<map> 12 #include<stack> 13 #include<queue> 14 #include<cstdlib> 15 #include<ctime> 16 using namespace std; 17 #define INF 0x3f3f3f3f 18 typedef long long ll; 19 int gcd(int a, int b){return b==0?a:gcd(b,a%b);} 20 21 const int MOD = 1e9 + 7; 22 23 int main() 24 { 25 // freopen("input1.txt", "r", stdin); 26 // freopen("output.txt", "w", stdout); 27 int n, x, k = 0; 28 ll ans = 1; 29 scanf("%d", &n); 30 while(n--) 31 { 32 scanf("%d", &x); 33 k++; 34 if(x < 2 * k - 1) 35 { 36 ans = ans * k % MOD; 37 k--; 38 } 39 } 40 for(int i = 2; i <= k; i++) 41 ans = ans * i % MOD; 42 printf("%d\n", (int)ans); 43 return 0; 44 }
以上是关于AtCoder 2316 思维题的主要内容,如果未能解决你的问题,请参考以下文章
AtCoder Beginner Contest 100 C(思维)
CODE FESTIVAL 2017 qual A C Palindromic Matrix(思维题)