• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            posts - 21,  comments - 9,  trackbacks - 0
             

            給出一棵二分搜索樹,再給一個節點編號n,求以這個節點為根節點的子樹葉子節點的最大值與最小值。若n是奇數,那么他必然是個葉子節點,最大最小都是他自己。否則求n所在的層數,他的層數就是他的因子中2的個數(規律),轉化為求n的因子中2的個數。而2的個數取決于n的二進制表示中最后一個1所處的位置i,因為之前的某幾個1,假設處于j(j>i),那么n可以表示為2^j+2^i+2^x(x>i且個數未定)=2^i*(1+2^(j-i)+2^(x-i)),看見米有,n必須有i個因子2.求出i的值后,即層數,可得n的左右各有num=2^i-1個兒孫(女),不信請看圖,概不解釋。那么最小值就是n-num,最大值就是n+num.那馬怎么求num呢,這時就可以請出神奇的位運算了(以速度"嗖嗖嗖"的快而揚名ACM界),首先是確定二進制n后綴連續0的個數,這樣想:怎么取出這i個0呢?其實不必考慮這個掣肘的問題,咱們直接跑到結果上考慮,就是求2^i-1,你花仙米有,這是個等差數列的前n項和:2^0+2^1+2^2+……+2^(i-1).那么這又是個什么形式呢,這就是二進制只有連續i個1的(其余都是前導0)數的十進制表示形式,OK,好辦了,利用系統自動轉換功能,咱們只需把這i個1羅列出來即可:把n的后i個0變成1,可采取如下形式n^(n|n-1),稍微解釋下,n|n-1是將后i個0變成1,把第i+1個1變成0,然后和n抑或一下,得到什么?哈,就是2^i-1,即i個1的十進制形式,代碼就不放了,上面明白了實現很簡單的!
            那啥,轉載務必注明:Pzjay原創呃!

            本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/shifuwawa/archive/2010/01/07/5153446.aspx

            以下是我根據上面的描述寫出來的代碼,一次AC,0MS
            #include<iostream>
            using namespace std;
            int main()
            {
             int n;
             cin>>n;
             while(n--)
             {
              int k;
              cin>>k;
              if(k%2!=0)
              {
               cout<<k<<" "<<k<<endl;
               continue;
              }
              int num=k^(k|k-1);
              cout<<k-num<<" "<<k+num<<endl;
             }
             return 0;
            }

            posted @ 2010-08-19 13:13 崔佳星 閱讀(1087) | 評論 (0)編輯 收藏
            不得不說poj 2305是一道進制轉換的經典題目。一開始我沒有考慮到整除的情況。所以總是WA。后來加了一個判斷就AC了。
            #include<iostream>
            #include<cstring>
            using namespace std;
            char s1[1005],s2[15];
            int main()
            {
             int n;
             while(cin>>n&&n)
             {
              cin>>s1>>s2;
              __int64 a=0,b=0;int len1,len2;
              len1=strlen(s1);len2=strlen(s2);
              for(int i=0;i<len2;i++)
              {
               a*=n;
               a+=s2[i]-'0';
              }
              for(int j=0;j<len1;j++)
              {
               b*=n;
               b+=s1[j]-'0';
               if(b>=a)
                b%=a;
              }
              int k=0;
              if(b==0)
              {
               cout<<"0"<<endl;
               continue;
              }
              while(b!=0)
              {
               s2[k++]=b%n+'0';
               b/=n;
              }
              s2[k]='\0';
              int len=strlen(s2);
              for(k=len-1;k>=0;k--)
               cout<<s2[k];
              cout<<endl;
             }
             return 0;
            }
            posted @ 2010-08-19 11:26 崔佳星 閱讀(1144) | 評論 (0)編輯 收藏
            這應該是一道DP題。下面的代碼是我見過的最短的代碼。拿出來跟大家分享。
            #include<iostream>
            #include<stdio.h>
            using namespace std;
            #define max(a,b) ((a)>(b)?(a):(b))
            int arrival[1450];
            int trip[1450];
            int time[1450];
            int n,t,m;
            int main()
            {
             int test;
             cin>>test;
             while(test--)
             {
              cin>>n>>t>>m;
              for(int i=1;i<=m;i++)
               scanf("%d",arrival+i);
              trip[0]=time[0]=0;
              for(int j=1;j<=m;j++)
              {
               time[j]=max(time[max(j-n,0)],arrival[j])+2*t;
               trip[j]=trip[max(j-n,0)]+1;
              }
              printf("%d %d\n",time[m]-t,trip[m]);
             }
             return 0;
            }


            然后是該作者的介紹

            題目大意:有一些汽車在左岸,你要用一條小破船把它們拉到右岸去。每個測試點包含多個測試數據。第一行的整數C表示測試數據的數目。接下來每個測試數據的第一行為三個整數N, T, M表示一次可以運送N輛汽車,到達對岸的時間為T,汽車的總數是M。接下來的M行每行有一個整數,表示這輛汽車什么時候會來到左岸。對于每個測試數據,輸出兩個整數,分別是最少要耗用多少時間(包括你等車的時間,就是從0開始直到最后一輛車到達右岸),以及在這個前提下你最少要運送多少次。只要到右岸去就算作一次。

            這個題出在DP專場不太合適……事實上本人用貪心的手段就解決了這個問題。

            貪心策略:先運送M % N輛汽車到對岸(就是M除上N的余數),之后每次運N輛汽車,直到運完為止。這里的意思是,只有船上確實有了這么多車才出發,在此之前等著那些車來。對于這個策略的證明各位可以使用數學歸納法,比較簡單,這里就不耗費篇幅了。

            posted @ 2010-08-18 21:18 崔佳星 閱讀(1154) | 評論 (0)編輯 收藏

            DFS題目啊。看通過率就知道非常簡單的。一下付代碼,大家自己看下。
            #include<iostream>
            using namespace std;
            char array[100][100];
            int n,m;int count=0;
            void dfs(int i,int j)
            {
             if(i<0||i>n||j<0||j>m)
              return ;
             if(array[i][j]!='W')
              return ;
             array[i][j]='.';
             dfs(i-1,j);dfs(i+1,j);dfs(i,j-1);dfs(i,j+1);dfs(i-1,j-1);dfs(i-1,j+1);dfs(i+1,j-1);dfs(i+1,j+1);
            }
            void check()
            {
             int i,j;
             for(i=0;i<n;i++)
             {
              for(j=0;j<m;j++)
              {
               if(array[i][j]=='W')
               {
                dfs(i,j);
                count++;
               }
              }
             }

            }
            int main()
            {
             cin>>n>>m;
             for( int i=0;i<n;i++)
             {
              for(int j=0;j<m;j++)
              {
               cin>>array[i][j];
              }
             }
             check();
             cout<<count<<endl;
             return 0;
            }

            posted @ 2010-08-18 19:20 崔佳星 閱讀(1234) | 評論 (0)編輯 收藏
            這道題目視枚舉題。直接枚舉各個長度,然后求最小面積即可。
            #include<iostream>
            using namespace std;
            int main()
            {
             int test;
             cin>>test;
             while(test--)
             {
              int n;
              cin>>n;
              int min=100000000;
              int area;
              int k;
              for(int i=1;i<=n;i++)
              {
               for(int j=1;i*j<=n;j++)
               {
                if(n%(i*j)==0)
                {
                 k=n/(i*j);
                 area=i*j+i*k+j*k;
                 if(area<min)
                  min=area;
                }
               }
              }
              cout<<min*2<<endl;
             }
             return 0;
            }
            posted @ 2010-08-18 17:01 崔佳星 閱讀(249) | 評論 (0)編輯 收藏

            這是一道模擬題。說白了就是石頭剪子布的問題。此題的關鍵點是要開兩個數組。一個是原來的。一個是改動后的,每次改動完之后都要用改動之后的初始化原來的一次。下面請看代碼。我把函數分的比較詳細。便于大家閱讀。
            #include<iostream>
            using namespace std;
            char array[102][102];
            char temp[102][102];
            int r,c,n;
            void init()
            {
             int i,j;
             for( i=1;i<=r;i++)
              {
               for( j=1;j<=c;j++)
               {
                array[i][j]=temp[i][j];
               }
              }
            }
            void change(int i,int j)
            {
             if(array[i][j]=='R')
             {
              if(i>1&&array[i-1][j]=='S')
               temp[i-1][j]='R';
              if(i+1<=r&&array[i+1][j]=='S')
               temp[i+1][j]='R';
              if(j>1&&array[i][j-1]=='S')
                temp[i][j-1]='R';
              if(j+1<=c&&array[i][j+1]=='S')
                temp[i][j+1]='R';
             }
             else
              if(array[i][j]=='P')
             {
              if(i>1&&array[i-1][j]=='R')
               temp[i-1][j]='P';
              if(i+1<=r&&array[i+1][j]=='R')
                temp[i+1][j]='P';
              if(j>1&&array[i][j-1]=='R')
                temp[i][j-1]='P';
              if(j+1<=c&&array[i][j+1]=='R')
                temp[i][j+1]='P';
             }
             else
              if(array[i][j]=='S')
             {
              if(i>1&&array[i-1][j]=='P')
               temp[i-1][j]='S';
              if(i+1<=r&&array[i+1][j]=='P')
                temp[i+1][j]='S';
              if(j>1&&array[i][j-1]=='P')
                temp[i][j-1]='S';
              if(j+1<=c&&array[i][j+1]=='P')
                temp[i][j+1]='S';
             }
            }
            void occupy()
            {
             int i,j;
             while(n--)
             {
              for(i=1;i<=r;i++)
               {
                for(j=1;j<=c;j++)
                {
                 change(i,j);     
                }
               }
              init();
             }

            }
            int main()
            {
             int test;
             cin>>test;
             int i,j;
             while(test--)
             {
              cin>>r>>c>>n;
              for( i=1;i<=r;i++)
              {
               for( j=1;j<=c;j++)
               {
                cin>>array[i][j];
                temp[i][j]=array[i][j];
               }
              }
              /////////////OK 輸入字符完畢。
              occupy();
              for( i=1;i<=r;i++)
              {
               for( j=1;j<=c;j++)
               {
                cout<<array[i][j];
               }
               cout<<endl;
              }
              if(test!=0)
               cout<<endl;
             }
             return 0;
            }

            posted @ 2010-08-18 16:13 崔佳星 閱讀(1011) | 評論 (0)編輯 收藏
            這個題首先要把輸入的坐標轉化成鄰接矩陣的形式。之后再利用鄰接矩陣使用普里姆算法計算最小生成樹。并對其中的邊進行排序。找出減去S個較大的后最大的那一個。因為較大的那幾個可以用衛星傳輸
            #include<iostream>
            #include<cmath>
            #include<algorithm>
            #include<stdio.h>
            using namespace std;
            typedef struct
            {
             double x;
             double y;
            }point;
            point array[505];
            double len[505][505];
            double kk[505],next[505];
            double re[505];
            int sa,num;
            double dis(point first,point second)
            {
             return sqrt((first.x-second.x)*(first.x-second.x)+(first.y-second.y)*(first.y-second.y));
            }
            void prim(int n)
            {
             int i,j;
              //////////讀入數據完畢。開始構建鄰接矩陣
              for(i=0;i<num;i++)
              {
               for(j=0;j<num;j++)
               {
                len[i][j]=15000000;
               }
              }
              for(i=0;i<num;i++)
              {
               for(j=0;j<num;j++)
               {
                if(i!=j)
                 len[i][j]=dis(array[i],array[j]);
               }
              }
              for(i=0;i<num;i++)
              {
               kk[i]=len[0][i];
               next[i]=0;
              }
              /////////鄰接矩陣構建完畢
              int count=0;i=0;
              while(count<num-1)
              {
               if(next[i]!=-1)
               {
                for(j=0;j<num;j++)
                {
                 if(i!=j&&next[j]!=-1)
                 {
                  if(len[i][j]<kk[j])
                  {
                   kk[j]=len[i][j];
                   next[j]=i;
                  }
                 }
                }
                next[i]=-1;
                double max=999999999;int k;
                for(j=0;j<num;j++)
                {
                 if(kk[j]<max&&next[j]!=-1)
                 {
                  k=j;
                  max=kk[j];
                 }
                }
                re[count]=max;
                i=k;
                count++;
               }
              }
            }
            int main()
            {
             int n;
             cin>>n;
             int i;
             while(n--)
             {
              cin>>sa>>num;
              for( i=0;i<num;i++)
              {
               scanf("%lf%lf",&array[i].x,&array[i].y);
              }
              prim(0);
              sort(re,re+num-1);
              printf("%.2f\n",re[num-1-sa]);
             }
             return 0;
            }
            posted @ 2010-08-18 14:39 崔佳星 閱讀(1169) | 評論 (0)編輯 收藏

            pku2126 poj2126
            題目大意:
            給定多項式的系數,問這個多項式能不能分解!
            如果能輸出NO 否則輸出YES
            實系數多項式分解定理:
            當n<2的時候不能分解輸出YES
            當n==2的時候如果有實數根就能分解輸出NO   否則不能分解輸出YES
            當n>2的時候一定能分解,那么輸出NO

            #include<iostream>
            using namespace std;
            int array[25];
            bool root(int a,int b,int c)
            {
             if(b*b>=4*a*c)
              return true;
             else
              return false;
            }
            int main()
            {
             int n;
             cin>>n;
             for(int i=0;i<=n;i++)
             {
              cin>>array[i];
             }
             if(n<=1)
              cout<<"YES"<<endl;
             else
              if(n==2)
              {
               if(root(array[0],array[1],array[2]))
                cout<<"NO"<<endl;
               else
                cout<<"YES"<<endl;
              }
              else
               cout<<"NO"<<endl;
              return 0;

            }

            posted @ 2010-08-17 16:02 崔佳星 閱讀(1080) | 評論 (0)編輯 收藏
            3096暴力求解,0M通過
            #include<stdio.h>
            #include<iostream>
            #include<cstring>
            using namespace std;
            char str[85];
            char first[3],second[3];
            int main()
            {
             first[2]='\0',second[2]='\0';
             while(gets(str))
             {
              bool flag=true;
              if(str[0]=='*')
               break;
              int len=strlen(str);
              for(int i=0;i<len;i++)
              {//從第幾個開始找起
               for(int j=1;j<(len-1)&&i+j<len;j++)
               {////////這個是間隔
                first[0]=str[i];first[1]=str[j+i];
                for(int k=i+1;k<len&&k+j<len;k++)
                {
                 second[0]=str[k];second[1]=str[k+j];
                 if(strcmp(first,second)==0)
                  flag=false;
                }
                
               }
              }
              if(flag)
               cout<<str<<" is surprising."<<endl;
              else
               cout<<str<<" is NOT surprising."<<endl;
             }
             return 0;
            }
            posted @ 2010-08-16 11:34 崔佳星 閱讀(1084) | 評論 (0)編輯 收藏
            這個題就是用一個遞歸轉化數字。10以下的不用轉換。
            #include<iostream>
            using namespace std;
            int k;
            int ff(int a)
            {
             int sum=1;
             for(int i=0;i<a;i++)
              sum*=10;
             return sum;
            }
            void convert(int a)
            {
             if(k/ff(a)==0)
              return ;
             else
             {
              if(k%ff(a)>=ff(a)/2)
               k=k/ff(a)+1;
              else
               k=k/ff(a);
              k*=ff(a);
              convert(a+1);  
             }
            }
            int main()
            {
             int n;
             cin>>n;
             while(n--)
             {
              cin>>k;
              if(k<10)
              {
               cout<<k<<endl;
               continue;
              }
              convert(1);
              cout<<k<<endl;
             }
             return 0;
            }
            posted @ 2010-08-16 11:01 崔佳星 閱讀(851) | 評論 (0)編輯 收藏
            僅列出標題
            共3頁: 1 2 3 
            <2025年5月>
            27282930123
            45678910
            11121314151617
            18192021222324
            25262728293031
            1234567

            常用鏈接

            留言簿(1)

            隨筆分類

            隨筆檔案

            文章分類

            文章檔案

            搜索

            •  

            最新評論

            閱讀排行榜

            評論排行榜

            国产亚洲色婷婷久久99精品| 精品视频久久久久| 亚洲AV无码1区2区久久| 99国产欧美精品久久久蜜芽| 久久99精品国产一区二区三区 | 麻豆AV一区二区三区久久| 久久国产色AV免费看| 国产呻吟久久久久久久92| 亚洲国产天堂久久综合| 久久91亚洲人成电影网站| 一本色综合久久| 国产成人无码精品久久久免费| 亚洲精品无码久久久| 精品久久久久久中文字幕| 亚洲国产视频久久| 中文字幕亚洲综合久久2| 日韩人妻无码一区二区三区久久 | 久久精品成人欧美大片| 俺来也俺去啦久久综合网| 亚洲AⅤ优女AV综合久久久| 97精品伊人久久久大香线蕉| 中文字幕久久精品无码| 日本精品久久久久影院日本| 久久国产精品国产自线拍免费 | 欧美国产成人久久精品| 国产成人久久AV免费| 亚洲午夜久久久久久久久久| 久久无码国产| 欧美午夜精品久久久久久浪潮| 青青草原1769久久免费播放| 久久国产精品99精品国产| 亚洲香蕉网久久综合影视| 久久无码AV一区二区三区| 人妻中文久久久久| 久久久人妻精品无码一区 | 久久精品国产色蜜蜜麻豆| 狠狠色丁香久久综合婷婷| 国产亚洲欧美成人久久片| 久久精品国产亚洲AV高清热| 久久精品麻豆日日躁夜夜躁| 精品国产乱码久久久久久郑州公司 |