poj 3126 容器+素數篩法
阿新 • • 發佈:2019-02-10
主要路徑
— — 它是一個不時改變這樣的事情,為了不讓敵人在黑暗中的安全問題。
— — 但你看,我選擇了我的號碼 1033年很好的理由。我是總理,你知道 !
— — 我知道,所以你的新號碼 8179 也是一個素數。你將不得不在你辦公室的門上四舊的貼上四個新的數字。
— — 不,它不是那麼簡單。假設我更改的第一個數字為 8,然後將讀取數不是素數的 8033 !
— — 我明白了,被總理你受不了吃非質數開你的門甚至幾秒鐘。
— — 正確 !所以我必須發明一種方案從 1033年 8179 乘去質數的路徑只有一個數字從一個總理改的下一個素數。
現在,財政部長,,一直在偷聽的人進行了干預。
— — 沒有不必要的開支,請 !我碰巧知道一個數字的價格是一英鎊。
— — 嗯,在這種情況下我需要一個電腦程式,儘量減少費用。你不知道一些非常廉價的軟體大師,是嗎?
— — 事實上,我做。你看,這個程式設計競賽地去......幫助總理找最便宜的主要路徑之間任何兩個給定四位數素數 !第一個數字必須非零,當然是。在上述情況下,這裡有一個解決方案。
時間限制: 1000MS | 記憶體限制: 65536 K |
共提交: 22998 | 接受: 12745 |
描述
內閣部長們相當被擾亂了來自首席的安全說明他們會有改變對他們的辦公室的四位數房間號的訊息。— — 它是一個不時改變這樣的事情,為了不讓敵人在黑暗中的安全問題。
— — 但你看,我選擇了我的號碼 1033年很好的理由。我是總理,你知道 !
— — 我知道,所以你的新號碼 8179 也是一個素數。你將不得不在你辦公室的門上四舊的貼上四個新的數字。
— — 不,它不是那麼簡單。假設我更改的第一個數字為 8,然後將讀取數不是素數的 8033 !
— — 我明白了,被總理你受不了吃非質數開你的門甚至幾秒鐘。
— — 正確 !所以我必須發明一種方案從 1033年 8179 乘去質數的路徑只有一個數字從一個總理改的下一個素數。
現在,財政部長,,一直在偷聽的人進行了干預。
— — 沒有不必要的開支,請 !我碰巧知道一個數字的價格是一英鎊。
— — 嗯,在這種情況下我需要一個電腦程式,儘量減少費用。你不知道一些非常廉價的軟體大師,是嗎?
— — 事實上,我做。你看,這個程式設計競賽地去......幫助總理找最便宜的主要路徑之間任何兩個給定四位數素數 !第一個數字必須非零,當然是。在上述情況下,這裡有一個解決方案。
1033此解決方案的成本是 6 磅。請注意,數字 1 了貼上在步驟 2 中不可以重用的最後一步 — — 必須購買新的 1。
1733年
3733
3739
3779
8779
8179
輸入
一線與正數: 測試用例 (頂多 100) 數目。然後為每個測試用例,一條線與兩個數字隔開的空白。這兩個數字是四位數質數 (沒有前導零)。輸出
每個案件,無論是用數字說明最小成本或包含不可能一詞的的一行。示例輸入
3 1033 8179 1373 8017 1033 1033
示例輸出
6 7 0
#include<iostream> #include<algorithm> #include<queue> using namespace std; const int N=10000; const int INF=10000; bool isprime[N]; void initprime() { fill(isprime,isprime+N,true); // for(int i=0;i<N;i++) // isprime[i]=true; for(int i=2;i<N;i++) //將所有的素數標記為真 if(isprime[i]) for(int j=i*i;j<N;j+=i) isprime[j]=false; } int d[N];// 存到達某點的步數 還有標記的作用 int BFS(int begin,int end) //寬搜一下子 { int i,j; queue<int> q; for(i=1000;i<N;i++) d[i]=INF; //初始化為無窮大 q.push(begin);//將起點放入容器 d[begin]=0; //並且該點為0 while(q.size())//容器大小為真時 繼續 { int p=q.front();//取出第一個元素賦給p q.pop(); //並且刪除該點 if(p==end) //控制結束條件 找到該點直接結束 break; for(i=1;i<=1000;i*=10)//i共可進行3次迴圈 { int m=(p/i)%10; //1234 取每個位數上的數 for(j=0;j<=9;j++)// 1234 在 123(0到9)之間遍歷一遍 且不會遍歷取出來的m 由此實現 了題目的要求 { if(j==m) continue; if(j==0&&i==1000) continue; int n=p+(j-m)*i;//得到某一個數 if(isprime[n]&&d[n]==INF)//d[]陣列可以實現標記 還有步數的疊加 { q.push(n); //將1000到9999裡裡面的所有素數都求出來 d[n]=d[p]+1; //到達該素數所用的步數 } } } } return d[end]; } int main() { int t,begin,end; initprime();//實現標記素數 cin>>t; while(t--) { cin>>begin>>end; int res=BFS(begin,end); if(res==INF) cout<<"impossible!"<<endl; else cout<<res<<endl; } return 0; }