弱校连萌题目链接:http://acm.bnu.edu.cn/v3/contest_show.php?cid=5772#problem/G
需要先想到出现循环节意味着出现了以前出现过的余数
然后就自己手写一个大数除法
后来看别人博客发现其实不用STL也可以 检查余数是否出现过可以是常数级的 因为除数不大于3000 所以开一个3010的数组来存余数标记即可
当然我还是用的map 因为复杂度实在太松了
这题烦得很
注意“输出前50位”是指所有数字加起来50位... 不是小数点后50位...(哭晕在厕所
然后处理余数的时候大于1的部分一次就搞定了
我真是太年轻以为还有好多种可能... 还搞了一个bitnum来统计小数点前有几次除法过程...
然后再注意出来以后 100/6应该输出16.(6) 1000/6应该输出166.(6) 0/1应该输出0.(0)
还有 写模拟题真的是要头脑清醒再去写
这道题从昨天早上写到昨天晚上
像这种题还有之前那道象棋 虽然什么算法都没考 但是很考验思维的缜密
写之前一定一定要有一个大概的代码架构于心
写了哪里要全部心理有数 要记得 不能写了这里等一下就忘了这里在干什么
出了问题在改的时候一定要确保无论何时都能undo到之前的任何一个状态
总之就是 精神状态要好 精神要高度集中 然后一气呵成
凌乱的代码如下 给一个错误的示范TAT
#include <cstdio> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> #include <cmath> #include <set> #include <queue> #include <stack> #include <map> #include <vector> using namespace std; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> P; ll a[10000]; int main() { //freopen("in.txt", "r", stdin); //freopen("out.txt", "w", stdout); int n, m; while(scanf("%d%d", &n, &m) == 2) { map<int, int> check; int q, r; int bitnum; int stepcnt = 0; int lp, rp; if(n < m) bitnum = 0; else bitnum = 1; q = n / m; r = n % m; printf("%d/%d = ", n, m); int pt = 0; while(true) { a[pt++] = n / m; r = n%m; if(check.count(r)) { lp = check[r]+1; rp = stepcnt; break; } else { check[r] = stepcnt; } n = r*10; stepcnt++; } for(int i = 0; i < pt; i++) { if(i == bitnum) { if(i == 0) { printf("%d", a[i]); printf("."); continue; } else printf("."); } if(i == lp) printf("("); printf("%d", a[i]); if(i == rp) { printf(")\n"); break; } if(i >= 50) { printf("...)\n"); break; } } printf(" %d = number of digits in repeating cycle\n", rp - lp + 1); printf("\n"); } return 0; }
时间: 2024-10-10 10:40:18