码迷,mamicode.com
首页 > 其他好文 > 详细

AtCoder 2316 思维题

时间:2017-08-15 21:17:16      阅读:129      评论:0      收藏:0      [点我收藏+]

标签:自己   表示   https   gcd   inf   cti   freopen   get   队列   

题目链接: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 思维题

标签:自己   表示   https   gcd   inf   cti   freopen   get   队列   

原文地址:http://www.cnblogs.com/roMxx/p/7367418.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!