大概每日N题(非课内难度)
被工大杯的各位julao打击到了的 L同学决定大概 每天刷题, 绝对不咕 , 如果没有人问课内的问题的话就在这里写点竞赛难度的题吧.
题1 P1192 台阶问题
题目描述
有N级的台阶,你一开始在底部,每次可以向上迈最多K级台阶(最少1级),问到达第N级台阶有多少种不同方式。
输入格式
两个正整数N,K。
输出格式
一个正整数,为不同方式数,由于答案可能很大,你需要输出ansbmod 100003后的结果。
题解
复杂度O(nk).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 #include <iostream> using namespace std;#define MAXN 100010 #define MOD 100003 int n,k;int data[MAXN] = {1 , 0 };int main () { cin>>n>>k; for (int i = 1 ; i <= n; ++ i){ for (int j = 1 ; j <= k; ++ j){ if (i-j>=0 ){ data[i] += data[i-j]; } } data[i] %= MOD; } cout<<data[n]<<endl; return 0 ; }
题2 P1025 数的划分
题目描述
1 2 3 4 5 6 7 8 9 将整数n分成k份,且每份不能为空,任意两个方案不相同(不考虑顺序)。 例如:n=7,k=3,下面三种分法被认为是相同的。 1,1,5; 1,5,1; 5,1,1; 问有多少种不同的分法。
输入格式
n,kn,k (6<n≤200, 2≤k≤6)
输出格式
1个整数,即不同的分法。
题解
DFS暴搜即可, 划分的时候保证升序防止出现重复.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 #include <iostream> using namespace std;#define MAXN 210 #define MAXM 7 int n,k;int classmateL (int n, int k, int min) { if (k == 1 ){ return 1 ; } int ans = 0 ; for (int i = min; i <= n / k; ++ i ){ ans += classmateL (n - i, k - 1 , i); } return ans; } int main () { cin>>n>>k; cout<<classmateL (n,k,1 ); return 0 ; }
题3 P1057 传球游戏
题目描述
1 2 3 4 5 上体育课的时候,小蛮的老师经常带着同学们一起做游戏。这次,老师带着同学们一起做传球游戏。 游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同学可以把球传给自己左右的两个同学中的一个(左右任意),当老师再次吹哨子时,传球停止,此时,拿着球没有传出去的那个同学就是败者,要给大家表演一个节目。 聪明的小蛮提出一个有趣的问题:有多少种不同的传球方法可以使得从小蛮手里开始传的球,传了mm次以后,又回到小蛮手里。两种传球方法被视作不同的方法,当且仅当这两种方法中,接到球的同学按接球顺序组成的序列是不同的。比如有三个同学1 号、2 号、3 号,并假设小蛮为1 号,球传了3 次回到小蛮手里的方式有1 ->2 ->3 ->1 和1 ->3 ->2 ->1 ,共2 种。
输入格式
一行,有两个用空格隔开的整数n,m(3≤n≤30,1≤m≤30)。
输出格式
1个整数,表示符合题意的方法数。
题解
先想着DFS暴搜, 发现T了, 才想起来复杂度是O(m^2).
于是DP:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 #include <iostream> using namespace std;int n,m,dp[50 ][50 ];int main () { cin>>n>>m; dp[0 ][0 ]=1 ; for (int i=0 ;i<m;i++) { for (int j = 0 ; j < n; j++) { if (dp[i][j]) { dp[i + 1 ][(j - 1 + n) % n] += dp[i][j]; dp[i + 1 ][(j + 1 ) % n] += dp[i][j]; } } } cout<<dp[m][0 ]; return 0 ; }
题4 P1996 约瑟夫问题
题目描述
n个人(n<=100)围成一圈,从第一个人开始报数,数到m的人出列,再由下一个人重新从1开始报数,数到m的人再出圈,……依次类推,直到所有的人都出圈,请输出依次出圈人的编号.
输入格式
n m
输出格式
出圈的编号
题解
本身想暴力, 结果莫名re和tle, 只得使用队列.
STL大法好
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 #include <iostream> #include <queue> using namespace std;int main () { int n,m; cin>>n>>m; queue<int > que; for (int i = 1 ; i <= n; ++ i){ que.push (i); } for (int i = 1 ; i <= n; ++ i){ for (int j = 1 ; j < m; ++ j){ que.push (que.front ()); que.pop (); } cout<<que.front ()<<" " ; que.pop (); } return 0 ; }