ADAMoracle 廣域節點網路即將正式上線
阿新 • • 發佈:2021-11-18
#include <bits/stdc++.h> using namespace std; /* vector resize解析: 如果n小於當前容器的大小,則將內容減少到其前n個元素,並刪除超出範圍的元素(並銷燬它們)。 如果n大於當前容器的大小,則通過在末尾插入所需數量的元素來擴充套件內容,以達到n的大小。如果指定了val,則將新元素初始化為val的副本,否則將對它們進行值初始化。 如果n也大於當前容器容量,將自動重新分配已分配的儲存空間。 請注意,此函式通過插入或擦除容器中的元素來更改容器的實際內容。 */ //高精度乘法模板(高精乘高精) vector<int> mul(vector<int> &A, vector<int> &B) { //只保留500個長度 if(A.size()>500) A.resize(500); if(B.size()>500) B.resize(500); int la = A.size(), lb = B.size(); vector<int> C(la + lb + 10, 0);//提前申請結果所需的空間 for (int i = 0; i < la; i++) for (int j = 0; j < lb; j++) C[i + j] += A[i] * B[j]; for (int i = 0; i < C.size(); i++) if (C[i] >= 10) { C[i + 1] += C[i] / 10; C[i] %= 10; } //處理前導0 while (C.size() > 1 && C.back() == 0)C.pop_back(); //只保留500個長度 if(C.size()>500) C.resize(500); return C; } //快速冪+高精度 a^b vector<int> qmi(int a, int b) { vector<int> ans; //結果陣列 ans.push_back(1); //底 vector<int> A; //上一個依賴項 A.push_back(a); while (b) { if (b & 1) ans = mul(ans, A); b >>= 1; A = mul(A, A); } return ans; } int main() { //計算 2^p-1的值 int p; cin >> p; vector<int> A = qmi(2, p);//利用快速冪,計算2^p //最後一位減去一個1,因為2^p最後一位肯定不是0,所以減1不會產生借位,直接減去即可! A[0]--; //一共多少位 printf("%d\n", (int) (p * log10(2) + 1)); //每行輸出50位,共輸出10行,不足500位時高位補0 int cnt = A.size(); for (int i = 0; i < 500 - cnt; i++) A.push_back(0); //倒著輸出 for (int i = 500 - 1; i >= 0; i--) { printf("%d", A[i]); if (i % 50 == 0) printf("\n"); } return 0; }
//P1045_check.cpp
#include <bits/stdc++.h> #include<windows.h> using namespace std; int main() { int t = 1000; char file[256]; //這裡的字首需要每次替換 string prefix = "P1045"; while (t) { t--; system("chcp 65001 > nul"); sprintf(file, "%s_data.exe > data.txt", prefix.c_str()); system(file); sprintf(file, "%s.exe < data.txt > %s.txt", prefix.c_str(), prefix.c_str()); system(file); sprintf(file, "%s_right.exe < data.txt > %s_right.txt", prefix.c_str(), prefix.c_str()); system(file); sprintf(file, "fc %s.txt %s_right.txt", prefix.c_str(), prefix.c_str()); if (system(file)) { printf("發現錯誤時的資料用例:\n"); system("type data.txt"); break; } } if (t == 0) cout << "沒有檢查出錯誤,測試通過!" << endl; return 0; }
//P1045_data.cpp
#include <bits/stdc++.h>
using namespace std;
int main() {
srand(time(0));
int n;
//n = rand() % 3100000 + 1000;
n = rand() % (3100000 - 1000) + 1001;
printf("%d \n", n);
}
//其它測試資料生成辦法
//https://blog.csdn.net/Njhemu/article/details/99539576
//P1045_right.cpp
#include <bits/stdc++.h> using namespace std; int f[1001], p, res[1001], sav[1001];//乘法要開兩倍長度 void result_1() { memset(sav, 0, sizeof(sav)); for (register int i = 1; i <= 500; i += 1) for (register int j = 1; j <= 500; j += 1) sav[i + j - 1] += res[i] * f[j];//先計算每一位上的值(不進位) for (register int i = 1; i <= 500; i += 1) { sav[i + 1] += sav[i] / 10;//單獨處理進位問題,不容易出錯 sav[i] %= 10; } memcpy(res, sav, sizeof(res));//cstring庫裡的賦值函式,把sav的值賦給res } void result_2()//只是在result_1的基礎上進行了細微的修改 { memset(sav, 0, sizeof(sav)); for (register int i = 1; i <= 500; i += 1) for (register int j = 1; j <= 500; j += 1) sav[i + j - 1] += f[i] * f[j]; for (register int i = 1; i <= 500; i += 1) { sav[i + 1] += sav[i] / 10; sav[i] %= 10; } memcpy(f, sav, sizeof(f)); } int main() { scanf("%d", &p); printf("%d\n", (int) (log10(2) * p + 1)); res[1] = 1; f[1] = 2;//高精度賦初值 while (p != 0)//快速冪模板 { if (p % 2 == 1)result_1(); p /= 2; result_2(); } res[1] -= 1; for (int i = 500; i >= 1; i -= 1)//注意輸出格式,50個換一行,第一個不用 if (i != 500 && i % 50 == 0)printf("\n%d", res[i]); else printf("%d", res[i]); return 0; }