pku1012 hdu1443約瑟夫環問題

2021-06-16 05:11:36 字數 1354 閱讀 9757

pku1012我寫了個鍊錶的暴力來直接打表發現只能打到k=9,到10就執行不了了;**在下面,而網上這一篇寫的打表居然可以,下面是我的草稿**:

#include

#include

struct link*head,*p,*fp;

int f[15];

void create(int n)

p->next=head;

}  

int solve(int m,int n,int k)

while(p->used==1);   

i++;

if(i==m)   

if(time==k) }}

void init()

}printf("i=%d %d/n",i,f[i]);

}}           

/*i=5 169

i=6 441

i=7 1872

i=8 7632

i=9 1740

*/int main()

我要了解的也就是:

令f[i]表示i個人玩遊戲報m退出最後勝利者的編號,最後的結果自然是f[n]

遞推公式

f[1]=0;

f[i]=(f[i-1]+m)%i;  (i>1)

有了這個公式,我們要做的就是從1-n順序算出f[i]的數值,最後結果是f[n]。因為實際生活中編號總是從1開始,我們輸出f[n]+1,由於是逐級遞推,不需要儲存每個f[i],程式也是異常簡單。

這篇博文針對本題寫的很好,問題是有個列舉的優化為什麼是k+1的倍數, k+1的倍數+1,我實在不明白,網上另一篇是這樣解釋的:

本題有幾點需要注意,否則很容易超時,

第一、運用公式j=(j+

m-1)

%(n-i);推導出下乙個出現的元素在第幾號位置,如果j

第二點。就是m,當只剩下k+1個數的時候,則上乙個消失的數一定是在目前僅剩的bad左邊或者是右邊,所以m%(k+1)==0或者1

有了這兩個條件,可以加快程式的速度

已經明白的部分寫了說明和**放在下面:

/*1012 accepted 132k 47ms c++ 705b 2011-01-18 22:17:34 */

#include

#include

using namespace std;

int f[15];

bool joseph(int k,int m)//2*k個人,報m;

{int i=0,len=k+k;

while(len>k){

i= (i+m-1)%len;

//編號必須從0開始才滿足這個公式;

//這點可以自己寫資料測下;

if(i

HDU和PKU的一些KMP題

如果看了我部落格介紹還沒懂kmp,則下面鏈結拿好。超好的kmp詳解 kmp詳解2 鏈結一鏈結二 擴充套件kmp 劉雅瓊ppt 擴充套件kmp 鏈結二 hdu 2087 剪花布條 求匹配次數 不可重疊 include include include include include using name...

HDU 6373 多校第六場1012 高中物理題

打比賽的時候不是我敲的,自己回去補題的時候寫了下,需要理解高中物理的自由落體和勻加速直線運動,將斜面上的不規則跳動轉化為兩個分運動,就可以了 include include include include include include include include include include...

1012 至少有 1 位重複的數字 hard

給定正整數 n,返回小於等於 n 且具有至少 1 位重複數字的正整數的個數。示例 1 輸入 20 輸出 1 解釋 具有至少 1 位重複數字的正數 20 只有 11 轉化為求都不重複的正整數的個數 例如高位是0 4th 3th 2th 1th total 0 0 0 1 9 9xa 9,0 0 0 1...