<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    E81086713E446D36F62B2AA2A3502B5EB155

    Java雜家

    雜七雜八。。。一家之言

    BlogJava 首頁 新隨筆 聯(lián)系 聚合 管理
      40 Posts :: 1 Stories :: 174 Comments :: 0 Trackbacks

    置頂隨筆 #

    如題:求連續(xù)正整數(shù)使得其和為給定的一個(gè)正整數(shù)
    下面給出我的解法,幾乎可以一步到位求出來
    實(shí)現(xiàn)代碼如下:
    /**
    *Author: Koth (
    http://weibo.com/yovn)
    *Date:  2011-12-01
    */
    #include 
    <stdlib.h>
    #include 
    <stdio.h>
    #include 
    <stdint.h>

    int solve(int Y,int& X){
        
    int m=0;
        
    int t=Y;
        
    if(Y<=0){
            X
    =Y;
            
    return 1;
        }
        
    while((t&1)==0){
            m
    +=1;
            t
    =t>>1;
        }
        
    if(m==32){
            X
    =Y;
            
    return 1;
        }
        
    int lastK=32;
        
    for(;lastK>m+1;lastK--){
            
    if(Y &(1<<(lastK-1))){
                
                
    break;
            }
                
        }

        
    //its a number st. exp(2,K)
        if(lastK==(m+1)){
            X
    =Y;
            
    return 1;
        }
        
    int k=1<<(m+1);
        
    int b=(Y>>m)-(1<<(lastK-m-1));

        X
    =(1<<(lastK-m-2))+(b+1-k)/2;

        
    if(X<=0){
            k
    =k-1-((0-X)<<1);
            X
    =0-X+1;
        }
        
        
    return k;

    }

    int main(int argc,char* argv[]){
        
    if(argc<=1){
            fprintf(stdout,
    "Usage:%s number\n",argv[0]);
            
    return 0;
        }
        
    int Y=atoi(argv[1]);
        
    int X=0;
        
    int k=solve(Y,X);
        fprintf(stdout,
    "%d=",Y);
        
    for(int i=0;i<k;i++){
            fprintf(stdout,
    "%d",X+i);
            
    if(i<(k-1)){
                fprintf(stdout,
    "+");
            }
        }
        fprintf(stdout,
    "\n");
        
    return 0;
    }
    posted @ 2011-12-01 22:09 DoubleH 閱讀(1777) | 評(píng)論 (2)編輯 收藏

    原題:

    Command Network

    Description

    After a long lasting war on words, a war on arms finally breaks out between littleken’s and KnuthOcean’s kingdoms. A sudden and violent assault by KnuthOcean’s force has rendered a total failure of littleken’s command network. A provisional network must be built immediately. littleken orders snoopy to take charge of the project.

    With the situation studied to every detail, snoopy believes that the most urgent point is to enable littenken’s commands to reach every disconnected node in the destroyed network and decides on a plan to build a unidirectional communication network. The nodes are distributed on a plane. If littleken’s commands are to be able to be delivered directly from a node A to another node B, a wire will have to be built along the straight line segment connecting the two nodes. Since it’s in wartime, not between all pairs of nodes can wires be built. snoopy wants the plan to require the shortest total length of wires so that the construction can be done very soon.

    Input

    The input contains several test cases. Each test case starts with a line containing two integer N (N ≤ 100), the number of nodes in the destroyed network, and M (M ≤ 104), the number of pairs of nodes between which a wire can be built. The next N lines each contain an ordered pair xi and yi, giving the Cartesian coordinates of the nodes. Then follow M lines each containing two integers i and j between 1 and N (inclusive) meaning a wire can be built between node i and node j for unidirectional command delivery from the former to the latter. littleken’s headquarter is always located at node 1. Process to end of file.

    Output

    For each test case, output exactly one line containing the shortest total length of wires to two digits past the decimal point. In the cases that such a network does not exist, just output ‘poor snoopy’.


    一開始沒仔細(xì)讀題,一看以為是最小生成樹呢,結(jié)果Krusal算法上去WA了,Prim算法也WA,修修改改一直WA,第二天發(fā)現(xiàn)本題是要在有向圖上面構(gòu)造最小樹形圖。

    按照著名的Zhu-Liu算法,仔細(xì)實(shí)現(xiàn)了一邊,終于AC了。
    按照我的理解總結(jié)下該算法,該算法對每個(gè)結(jié)點(diǎn),除根節(jié)點(diǎn)外尋找最小入邊,
    1)如果這些入邊不構(gòu)成環(huán),那么容易證明這些邊構(gòu)成最小樹形圖。
    證明:設(shè)加上根節(jié)點(diǎn)r一共N個(gè)點(diǎn),那么一共有N-1條邊,證明從r能到每個(gè)點(diǎn),若存在一點(diǎn)v,使得從r到v沒有路徑,那么,假設(shè)從v反向回退必然構(gòu)成環(huán),因?yàn)槊總€(gè)點(diǎn)除了r都有入邊,如果不構(gòu)成環(huán),該路徑可以無窮大。
    2)如果存在環(huán),我們把環(huán)收縮成一個(gè)點(diǎn),更新相應(yīng)的入邊和出邊,得到新的圖G',使得原問題在G'中等效:
    怎么收縮呢?
    假設(shè)我們把環(huán)收縮成環(huán)上的任意一點(diǎn)v,所有進(jìn)環(huán)的邊和出環(huán)的邊自動(dòng)變成v的邊(如果已有,取長度最短的),其余點(diǎn)標(biāo)記為刪除,更新不在環(huán)上的所有點(diǎn)進(jìn)入該環(huán)的長度cost為cost-cost(prev[x],x);其中點(diǎn)x為進(jìn)入環(huán)的邊在環(huán)上的端點(diǎn)。出邊保持不變。

    這里為什么這么更新?因?yàn)檫@樣更新使得我們的算法在新圖上是等效的。任何環(huán)的解決后意味著在新圖里面得為改收縮后的點(diǎn)尋找新的入邊,而實(shí)際的花費(fèi)應(yīng)該是新的入邊減去原有的入邊長度,我們的算法在找到環(huán)的時(shí)候就把環(huán)上所有的邊的長度計(jì)算在花費(fèi)內(nèi)了.而對出邊是沒有影響的。


    到這算法的框架基本出來了。當(dāng)為某點(diǎn)沒找到入邊的時(shí)候,意味著無解。為了加快無解的偵測,我們先運(yùn)行一遍DFS搜索,假如從根節(jié)點(diǎn)出發(fā),可觸及的節(jié)點(diǎn)數(shù)小于N-1(不含r)則意味著無解。反之,肯定有解。
    為什么?
    因?yàn)槿绻捎|及數(shù)小于N-1,意味著某點(diǎn)是不可觸及的,也就是原圖不是弱連通。對該點(diǎn)來說不存在從r到它的路徑。反之,從r到某點(diǎn)都有一條路徑,沿著該路徑就能找到結(jié)點(diǎn)的入邊。


    第二個(gè)問題是,如何快速偵測環(huán)呢?
    我使用了一個(gè)不相交集。回憶Krusal的算法實(shí)現(xiàn)里面也是使用不相交集來避免找產(chǎn)生環(huán)的最小邊。

    下面是我的代碼:

    // 3164.cpp : Defines the entry point for the console application.
    //

    #include 
    <iostream>
    #include 
    <cmath>


    using namespace std;

    typedef 
    struct _Point
    {

        
    double x;
        
    double y;

        
    double distanceTo(const struct _Point& r)
        {
              
    return sqrt((x-r.x)*(x-r.x)+(y-r.y)*(y-r.y));

        }

    }Point;



    const int MAX_V=100;
    const int MAX_E=10000;
    const double NO_EDGE=1.7976931348623158e+308;

    Point vertexes[MAX_V]
    ={0};
    int parents[MAX_V]={0};
    int ranks[MAX_V]={0};
    double G[MAX_V][MAX_V]={0};
    bool visited[MAX_V]={0};
    bool deleted[MAX_V]={0};
    int prev[MAX_V]={0};

    int nVertex=0;
    int nEdge=0;




    int u_find(int a)
    {
        
    if(parents[a]==a)return a;
        parents[a]
    =u_find(parents[a]);
        
    return parents[a];
    }
    void u_union(int a,int b)
    {
        
    int pa=u_find(a);
        
    int pb=u_find(b);
        
    if(ranks[pa]==ranks[pb])
        {
            ranks[pa]
    ++;
            parents[pb]
    =pa;
        }
    else if(ranks[pa]<ranks[pb])
        {
            parents[pa]
    =pb;
        }
        
    else
        {
            parents[pb]
    =pa;
        }
    }

    void DFS(int v,int& c)
    {

        visited[v]
    =true;
        
    for(int i=1;i<nVertex;i++)
        {
            
    if(!visited[i]&&G[v][i]<NO_EDGE)
            {
                c
    +=1;

                DFS(i,c);
            }

        }

    }



    void doCycle(int s,int t,double& cost)
    {
        memset(visited,
    0,sizeof(bool)*nVertex);
        
    int i=s;
        
    do
        {
            visited[i]
    =true;
            cost
    +=G[prev[i]-1][i];
            
    //cout<<"from "<<(prev[i]-1)<<" to "<<i<<" (cycle)"<<" weight:"<<G[prev[i]-1][i]<<endl;
            i=prev[i]-1;

        }
    while(i!=s);


        
    do
        {
            

            
    for(int k=0;k<nVertex;k++)
            {
                
    if(!deleted[k]&&!visited[k])
                {
                
                    
    if(G[k][i]<NO_EDGE)
                    {
                        
    if(G[k][i]-G[prev[i]-1][i]<G[k][s])
                        {


                            G[k][s]
    =G[k][i]-G[prev[i]-1][i];
                            
    //cout<<"1.update ["<<k<<","<<s<<"] at "<<i<<" as "<<G[k][s]<<endl;
                        }
                        

                    }
                    
    if(G[i][k]<NO_EDGE)
                    {
                        
    if(G[i][k]<G[s][k])
                        {

                            G[s][k]
    =G[i][k];
                            
    //cout<<"2.update ["<<s<<","<<k<<"] at "<<i<<" as "<<G[s][k]<<endl;
                        }
                        
                    }
                }
            }


            
    if(i!=s)
            {
                deleted[i]
    =true;
                
    //cout<<"mark "<<i<<" as deleted"<<endl;
            }
            i
    =prev[i]-1;


        }
    while(i!=s);



    }




    int main(void)
    {



        
        
    while(cin>>nVertex>>nEdge)
        {

            
    int s,t;

            
    int nv=0;
            
    bool cycle=0;
            
    double cost=0;
            memset(vertexes,
    0,sizeof(vertexes));
            memset(visited,
    0,sizeof(visited) );

            memset(deleted,
    0,sizeof(deleted));
            memset(G,
    0,sizeof(G));
            memset(prev,
    0,sizeof(prev));


            memset(ranks,
    0,sizeof(ranks));

            memset(parents,
    0,sizeof(parents));

            
    for(int i=0;i<nVertex;i++)
            {

                cin
    >>vertexes[i].x>>vertexes[i].y;
                parents[i]
    =i;
                
    for(int j=0;j<nVertex;j++)
                {
                    G[i][j]
    =NO_EDGE;
                }

            }
            
    for(int i=0;i<nEdge;i++)
            {

                cin
    >>s>>t;
                
    if(t==1||s==t)continue;
                G[s
    -1][t-1]=vertexes[s-1].distanceTo(vertexes[t-1]);

            }



            DFS(
    0,nv);
            
    if(nv<nVertex-1)
            {

                cout
    <<"poor snoopy"<<endl;
                
    continue;
            }



            
    do {
                cycle
    =false;
                
    for(int i=0;i<nVertex;i++){parents[i]=i;}
                memset(ranks,
    0,sizeof(bool)*nVertex);
            

                
    for (int i = 1; i < nVertex; i++) {
                    
    double minimum=NO_EDGE;
                    
    if(deleted[i])continue;
                    
    for(int k=0;k<nVertex;k++)
                    {
                        
    if(!deleted[k]&&minimum>G[k][i])
                        {
                            prev[i]
    =k+1;
                            minimum
    =G[k][i];
                        }
                    }
                    
    if(minimum==NO_EDGE)
                    {
                    

                        
    throw 1;
                    }
                    
    if (u_find(prev[i]-1== u_find(i)) {
                        doCycle(prev[i]
    -1,i, cost);
                        cycle 
    = true;
                        
    break;
                    }
                    
    else
                    {
                        u_union(i,prev[i]
    -1);
                    }

                }


            } 
    while (cycle);

            
    for (int i = 1; i < nVertex; i++) {
                
    if(!deleted[i])
                {
                    cost
    +=G[prev[i]-1][i];
                    
    //cout<<"from "<<(prev[i]-1)<<" to "<<i<<" weight:"<<G[prev[i]-1][i]<<endl;
                }

            }

            printf(
    "%.2f\n",cost);


        }


    }



    posted @ 2009-04-24 16:39 DoubleH 閱讀(2426) | 評(píng)論 (0)編輯 收藏

       今天買了本《算法概論》影印注釋版,仔細(xì)看了第一章,果然名不虛傳,很是吸引人。
    第一章的習(xí)題難度適中,這里抽出第35題來,這題是證明Wilson定理。
    Wilson定理:
       N是一個(gè)素?cái)?shù)當(dāng)且僅當(dāng): (N-1)! ≡ -1(mod N)

    證明:
      首先我們證明若N是素?cái)?shù),那么等式成立,對于N=2,這是很明顯的。以下證明N>2 的情形。
      1)若N是素?cái)?shù),那么關(guān)于N同余的乘法群G={1,2,3....N-1}
        群G每個(gè)元素都有逆元,映射 f:a -> a^-1 ,f(a)=a^-1 是一個(gè)一一映射。現(xiàn)在,任取一個(gè)元素,它的逆元要么是其它一個(gè)元素,或者是它本身。 我們假設(shè)其中元素x的逆元是它本身,那么x*x ≡1(mod N) =>(x+1)*(x-1)=K*N,而N是素?cái)?shù),所以要么x=N-1,要么x=1。也就是說,除了這兩個(gè)元素,其它的元素的逆元都是映射到別的元素的。而N>2,是奇數(shù),所以元素共有N-1個(gè),也就是偶數(shù)個(gè)元素。這樣,除了1和N-1外剩余的N-3個(gè)元素剛好結(jié)成兩兩一對(x,y)(逆元是唯一的)使得f(x)=y=x^-1,也就是xy≡1(mod N).
    現(xiàn)在把G的元素全部乘起來,讓互為逆元的元素組成一對那么(N-1)!=1*(N-1)*(x1*y1)*(x2*y2)...(xk*yk)≡1*(N-1)*1*1...1 (mod N)≡-1(mod N).
        這樣,我們證明了一個(gè)方向了,下面我們證明另一個(gè)方向

      2)若(N-1)! ≡ -1(mod N)成立,則N是素?cái)?shù),若不然,令 N是和數(shù)。則(N-1)!肯定整除N,因?yàn)镹的每個(gè)因子p滿足p>1,p<N。
       現(xiàn)在令(N-1)!=K1*N.又(N-1)! ≡ -1(mod N) => K1*N ≡ -1(mod N),由同余性質(zhì)知,存在K2使得K1*N+1=K2*N,兩邊同時(shí)除以N得K1+1/N=K2.顯然,這是不可能的,所以若(N-1)! ≡ -1(mod N)成立,則N是素?cái)?shù)

    證明完畢!

    這里用群的概念能夠簡化一定的描述,其實(shí)可以完全不用群的概念的,只不過這樣一來,描述更長點(diǎn),繁瑣點(diǎn)!





    posted @ 2009-04-10 22:38 DoubleH 閱讀(2047) | 評(píng)論 (1)編輯 收藏

    僅列出標(biāo)題  下一頁
    主站蜘蛛池模板: 亚洲乱码一二三四五六区| 亚洲男人av香蕉爽爽爽爽| 亚洲成Av人片乱码色午夜| 日韩一区二区三区免费播放| 成年人免费观看视频网站| 亚洲区视频在线观看| 国产免费爽爽视频免费可以看| 亚洲丁香婷婷综合久久| 天天拍拍天天爽免费视频| 亚洲色欲啪啪久久WWW综合网| 女人被弄到高潮的免费视频| 一级毛片一级毛片免费毛片| 亚洲性在线看高清h片| 久久成人18免费网站| 亚洲AV无码码潮喷在线观看| 四虎影视成人永久免费观看视频| 亚洲一区二区三区高清| 最近2019年免费中文字幕高清| 亚洲国产综合第一精品小说| 99久久免费国产精品特黄| 亚洲sm另类一区二区三区| 亚洲精品二区国产综合野狼| 18女人毛片水真多免费| 色噜噜亚洲男人的天堂| 国产一级做a爱免费视频| 最近免费中文在线视频| 精品免费久久久久国产一区| 亚洲欧美熟妇综合久久久久| www国产亚洲精品久久久日本| 中文永久免费观看网站| 亚洲黑人嫩小videos| 午夜a级成人免费毛片| 国产99久久久国产精免费| 久久久久亚洲av无码专区导航| 又黄又爽的视频免费看| 最好免费观看高清在线| 中中文字幕亚洲无线码| 亚洲国产精品国自产拍AV| 亚洲欧洲日本在线| 日韩成全视频观看免费观看高清 | 精品一区二区三区无码免费直播|