http://domen111.github.io/UVa-Easy-Viewer/?516
給一個數字
可以利用 stringstream 讀取輸入,取得所有數值就可以拿到
至於質因數分解的部分,我們可以藉由質數篩的過程當中紀錄每個數字第一次是被誰篩掉(也就是最小因數)
例如: 10 -> 2
9 -> 3
17 -> 17
如此一來,對於每個詢問
//By Koios1143
#include<iostream>
#include<sstream>
#include<cmath>
const int MaxN = 32768;
int fact[MaxN], ans[MaxN][2];
using namespace std;
string s;
bool fir;
int x,n,a,b,p,cnt,px;
int main(){
// 質數篩
for(long long i=2 ; i<=MaxN ; i++){
if(!fact[i]){
fact[i]=i;
for(long long j=i*i ; j<=MaxN ; j+=i){
if(!fact[j]){
fact[j]=i;
}
}
}
}
while(getline(cin,s)){
if(s=="0") break;
fir=true; n=1; px=0;
// 計算 X
stringstream ss;
ss<<s;
while(ss>>x){
if(fir) a=x;
else{
b=x;
n*=pow(a,b);
}
fir=!fir;
}
n--;
// 質因數分解
while(n!=1){
p=fact[n];
cnt=0;
while(n%p==0){
cnt++;
n/=p;
}
ans[px][0]=p;
ans[px][1]=cnt;
px++;
}
for(int i=px-1 ; i>=0 ; i--){
if(i!=px-1) cout<<" ";
cout<<ans[i][0]<<" "<<ans[i][1];
}
cout<<"\n";
}
return 0;
}
質數篩的複雜度為
每筆測資計算
每筆測資質因數分解時間複雜度約為
每筆測資輸出時間複雜度約為
其中,
總時間複雜度約為
http://domen111.github.io/UVa-Easy-Viewer/?10699
多筆輸入,每筆輸入包含一個正整數
跟上一題類似,先透過質數篩找到每個數的最小質因數
//By Koios1143
#include<iostream>
const int MaxN = 1e6+5;
int fact[MaxN];
using namespace std;
int n,cnt,p;
int main(){
for(long long i=2 ; i<=MaxN ; i++){
if(!fact[i]){
fact[i]=i;
for(long long j=i*i ; j<=MaxN ; j+=i){
if(!fact[j]){
fact[j]=i;
}
}
}
}
while(cin>>n && n){
cnt=0;
cout<<n<<" : ";
while(n!=1){
p=fact[n];
cnt++;
while(n%p==0){
n/=p;
}
}
cout<<cnt<<"\n";
}
return 0;
}
質數篩的複雜度為
每筆測資質因數分解時間複雜度約為
總時間複雜度約為
http://domen111.github.io/UVa-Easy-Viewer/?10789
給一串字串
先建立質數表,統計過後查表即可
//By Koios1143
#include<iostream>
using namespace std;
const int MaxN = 2002;
bool prime[MaxN];
string s;
int n,tbl[128];
string crt="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
int main(){
for(int i=0 ; i<=MaxN ; i++){
prime[i]=true;
}
prime[0] = prime[1] = false;
for(long long i=2 ; i<=MaxN ; i++){
if(prime[i]){
for(long long j=i*i ; j<=MaxN ; j+=i){
prime[j]=false;
}
}
}
cin>>n;
for(int Case=1 ; Case<=n ; Case++){
cin>>s;
cout<<"Case "<<Case<<": ";
for(int i=0 ; i<128 ; i++){
tbl[i]=0;
}
for(int i=0 ; i<s.size() ; i++){
tbl[s[i]]++;
}
bool out=false;
for(int i=0 ; i<crt.size() ; i++){
if(prime[tbl[crt[i]]] == true){
cout<<crt[i];
out=true;
}
}
if(!out){
cout<<"empty";
}
cout<<"\n";
}
return 0;
}
建表時間複雜度為
統計時間複雜度為
總時間複雜度為
http://domen111.github.io/UVa-Easy-Viewer/?11960
多筆測資,每筆測資包含一個正整數
先做質因數分解,並且透過以下的想法可以找出每個數的因數個數
我們可以觀察
其中的因數包含了
觀察一下會發現,這些因數都是由
也就是說我可以選擇要拿多少
所以我們得到若
話說回來,利用上述的性質,加上質因數分解,就可以輕鬆求出每個數值的因數個數
而由於題目只需要所有
//By Koios1143
#include<iostream>
const int MaxN = 1e6+5;
int fact[MaxN],ans[MaxN];
using namespace std;
int t,x;
int main(){
for(long long i=2 ; i<=MaxN ; i++){
if(!fact[i]){
fact[i]=i;
for(long long j=i*i ; j<=MaxN ; j+=i){
if(!fact[j]){
fact[j]=i;
}
}
}
}
for(int i=1 ; i<=MaxN ; i++){
// 後面要做乘法,所以預設值為 1
ans[i]=1;
}
for(int i=2 ; i<=MaxN ; i++){
int tmp=i;
while(tmp!=1){
int p=fact[tmp], cnt=0;
while(tmp%p==0){
tmp/=fact[tmp];
cnt++;
}
ans[i]*=(cnt+1);
}
}
// 預處理答案
int n=2,m=ans[2];
for(int i=2 ; i<=MaxN ; i++){
if(ans[i]>=m){
m=ans[i];
n=i;
}
ans[i]=n;
}
cin>>t;
while(t--){
cin>>x;
cout<<ans[x]<<"\n";
}
return 0;
}
質數篩的複雜度為
對所有數值做質因數分解,時間複雜度約為
預處理答案的時間複雜度為
每筆回答時間複雜度為
總時間複雜度為
SCIST 演算法 題解