hdoj N!

N!

Time Limit : 10000/5000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 27   Accepted Submission(s) : 8
Font: Times New Roman | Verdana | Georgia
Font Size: ← →

Problem Description

Given an integer N(0 ≤ N ≤ 10000), your task is to calculate N!

Input

One N in one line, process to the end of file.

Output

For each N, output N! in one line.

Sample Input

1
2
3

Sample Output

1
2
6
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define maxn 40000
using namespace std;
int f[maxn];
int main()
{
    int s,c,i,j,n,k;
    while(scanf("%d",&n)!=EOF){
     memset(f,0,sizeof(f));
     f[0]=1;
     for(i=2;i<=n;i++){
      c=0;
      for(j=0;j<maxn;++j){
       s=f[j]*i+c;
       f[j]=s%10;
       c=s/10;}}
       for(j=maxn;j>=0;--j)if(f[j])break;
       for(i=j;i>=0;--i)
       printf("%d",f[i]);
       printf("\n");}
    return 0;
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
### HDOJ 2062 Subset Sequence 的题目解析 HDOJ 2062 是一道关于子序列排列的题目,主要考察的是对字符串的操作以及递归或深度优先搜索(DFS)的应用。以下是对此题目的详细解析。 #### 题目描述 给定一个长度为 n 的整数集合 S 和一个目标子集 T,要求找出所有可能的子集顺序使得这些子集可以组成整个集合 S。具体来说,对于每一个子集 Ti ∈ T,Ti 中的所有元素必须连续出现在最终的结果中,并保持相对位置不变。 --- #### 解决方案概述 此问题可以通过 **回溯法** 来解决。回溯法是一种基于深度优先搜索的思想,在解决问题的过程中不断尝试不同的可能性并及时撤销不符合条件的选择[^4]。为了高效处理这个问题,需要注意以下几个方面: 1. **输入数据类型**: 输入中的某些数值较大,因此需要将涉及的数据类型设为 `long long` 类型以防止溢出[^1]。 2. **排序与预处理**: 如果题目中有隐含的要求(如字典序),则需提前对输入数据进行必要的排序操作[^3]。 3. **状态表示**: 使用布尔数组记录当前哪些元素已经被选入结果集中,从而避免重复选取同一元素。 4. **剪枝优化**: 在递归过程中加入合理的剪枝逻辑,减少不必要的计算开销。例如,当剩余未匹配项的数量不足以构成完整的子集时即可终止当前分支。 --- #### 实现细节 下面提供了一个 C++ 版本的具体实现代码示例: ```cpp #include <iostream> #include <vector> #include <algorithm> using namespace std; // 定义全局变量用于存储原始集合S及其大小N int N; vector<int> S, subset; // 子集T作为参数传入dfs函数 bool used[100]; // 记录某个数字是否被使用过 void dfs(vector<vector<int>> &res, vector<int> currentSubset) { if (currentSubset.size() == N) { // 当前路径已满足全部覆盖 res.push_back(currentSubset); return; } for (size_t i = 0; i < S.size(); ++i) { if (!used[i]) { bool valid = true; // 判断新增加的元素是否会破坏现有子集关系 int lastIdx = currentSubset.empty() ? -1 : find(S.begin(), S.end(), currentSubset.back()) - S.begin(); if (lastIdx != -1 && abs(i - lastIdx) > 1) continue; // 不允许间隔超过一位 used[i] = true; currentSubset.push_back(S[i]); dfs(res, currentSubset); // 继续向下探索 currentSubset.pop_back(); // 回退至上一层级 used[i] = false; } } } int main(){ cin >> N; S.resize(N); for(int i=0;i<N;++i){ cin >> S[i]; } fill(used, used+N, false); vector<vector<int>> result; vector<int> temp; sort(S.begin(), S.end()); // 排序以便后续输出更整齐 dfs(result, temp); // 输出所有的合法组合 for(auto vec:result){ for(auto num:vec){ cout << num << ' '; } cout << endl; } return 0; } ``` 上述代码通过递归调用 `dfs()` 函数来枚举所有符合条件的子集排列方式,并利用辅助数组 `used[]` 控制每一轮迭代所使用的元素不会发生冲突。 --- #### 常见错误及调试技巧 - 数据类型的选用不当可能导致运算结果越界或者精度丢失,尤其是在面对大数据量测试案例时应格外小心。 - 若程序运行效率低下,则考虑是否存在冗余计算或是缺乏有效的剪枝措施。 --- ###
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值