2014年8月12日 星期二

jQuery Mobile 載入新頁面

使用 jQuery Mobile 時,jQuery Mobile 預設是用 ajax 載入頁面的內容,所以使用連結或送出

表單到另一個頁面應是把 <body> 裡的資料載入呈現,body 以外的 script, js, css 不會再被重

新要求載入、執行。


測試程式碼:

<body>
    <div>
        <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b">
            <li><a href="link2.html">link2</a></li>                
        </ul>
        <a href="link2.html" data-role="none">link2</a>
    </div>
</body>

測試程式碼二:

<script type="text/javascript">
    $(document).ready(function() {
        alert('test');
    });
</script>

<body>
    <div>link test</div>
</body>
(script 放在 head 的 tag 之間)

(以上程式碼要在 head 引入 jQuery Mobile 的 js code)


 
(利用程式碼一連結程式碼二的頁面) 

(用 chrome 的 network 看,有載入所用到的檔案)


(程式碼二的 script 不會被執行) 

 (不會再載入用到的 script)


測試:

把 script 放在 body 裡時,script 有被執行,但是放在 body 之外的其他地方,script 不會被執

行,推測應該是只把 body 裡的程式碼載入呈現。



解決辦法:

關閉 jQuery Mobile 預設的 ajax:在 <a>、<form> 裡加入 data-ajax="false"。

修改程式碼一

<body>
    <div>
        <ul data-role="listview" data-inset="true" data-theme="c" data-dividertheme="b">
            <li><a href="link2.html" data-ajax="false">link2</a></li>                
        </ul>
        <a href="link2.html" data-role="none" data-ajax="false">link2</a>
    </div>
</body>

(script 成功被執行)

2014年8月6日 星期三

Yii2 registerJs

registerJs 可以用來插入 script,並設定插入位置、執行時機。

registerJs( $js, $position, $identified_name );

$js : 放入 script

$position :

有五種 : POS_HEAD、POS_BEGIN、POS_END、POS_READY、POS_LOAD

POS_HEAD:放在 <head> 和 </head> 之間

POS_BEGIN:放在 <body> 的一開始

                           ex : <body>
                                      <script type="text/javascript">
                                          ...
                                      </script>

                                      HTML....
                                  </body>

POS_END:放在 <body> 的最後 ( </body> 前 )

                           ex : <body>
                                      HTML....

                                      <script type="text/javascript">
                                          ...
                                      </script>
                                  </body>

POS_READY:測試時,發現放的位置和 POS_END 一樣

                            但所設定的 script 會放在 jQuery(document).ready(fuction(){ ... }); 裡

                           ex : <body>
                                      HTML....

                                      <script type="text/javascript">
                                         
                     jQuery(document).ready(function () {
                         ...
                     });
                                      </script>
                                  </body>

                           ready : 等到 HTML 的 tag 都產生後才執行 script,因為 script 裡面可能會有想

                                       要抓取 tag、對 tag 做設定,所以要等 tag 產生,否則 script 在執行時

                                       會有問題 。


POS_LOAD:測試時,發現放的位置和 POS_END 一樣

                          但所設定的 script 會放在 jQuery(window).load(fuction () { ... }); 裡

                           ex : <body>
                                      HTML....

                                      <script type="text/javascript">
                                         
                     jQuery(window).load(function () {
                         ...
                     });
                                      </script>
                                  </body>

                           load : 會等到所有網頁的資源都下載完後才執行 script,因為 scirpt 裡面可能

                                     會有想要抓取這些資源的資訊,所以要等這些資源下載完,否則 script

                                     在執行時會有問題。

                                     資源:ex : 圖片、flash、iframe

$identified_name : 

設定這組註冊 script 的名稱,預設為 null。如果有兩個註冊的名稱相同,後面的會覆蓋前面的

script。



使用前:

regitserJs 是放在 yii\web\View 裡面,如果要方便使用的話,可以先

use yii\web\View;

之後就可以 $this->registerJs( ... );


使用範例:

use yii\web\View;

$this->registerJs(

          "alert( "registerJs test" );" ,

          POS_HEAD,

          null
);

2014年7月25日 星期五

uva 10340 All in All

只要確定是否有一組 subsequence 為 sequence 即可,只要走訪一次被尋找的 string,當發現

有相同的字元時,就找下一個 sequence 的字元。


#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int main(void){
    char input[1000000],target[1000000];
    int i,j,k,outcome;

    while(scanf("%s %s",&target,&input)!=EOF){
        outcome=0;

        k=0;
        for(i=0;i<strlen(input);i++){

            if(target[k]==input[i]) k++;

            if(target[k]=='\0'){
                outcome=1;
                break;
            }
        }

        if(outcome==1){
            printf("Yes\n");
        }else{
            printf("No\n");
        }
    }



    return 0;
}

uva 10079 Pizza Cutting

把 0 ~ 10 計算出來就會比較有感覺,他是有個規律在。

0 : 1
1 : 2
2 : 4
3 : 7
4 : 11
5 : 16
6 : 22
7 : 29
8 : 37
9 : 46
10 : 56

從上面可以發現,下一個的塊數為上一個的塊數 + 這次的直線數量

如果接下來都是這樣,可以歸納出一個公式 : ( n ^ 2 + n ) / 2 + 1


接下來都會符合,因為:

最大塊數和這條直線可以在上一個最大塊數的情況下最多可以經過幾個區塊,每經過一個區

塊,就會多切出一塊;

最多可以經過幾個區塊跟上一個的直線數有關,區塊和區塊之間是由線分隔,兩條線最多只

會有一個交點,區塊之間由交點分隔,區塊 = 交點數 + 1,最多交點數為上一個的直線數。

Sn : n 條線最多可以切出的塊數

Sn = Sn-1 + n  => ( n ^ 2 + n ) / 2 + 1


注意:測資大小的範圍 : 0 <= N <= 210000000 => 可用 long long int

long long int 如果在 windows 下跑  210000000出現 overflow 的情況,這是因為環境的問

題,judge 的環境,long long int 可以處理這麼大的數字的。


#include <stdio.h>
#include <stdlib.h>

int main(void){
    long long int line;

    while(scanf("%lld",&line)!=EOF){
        if(line < 0) break;

        printf("%lld\n", ( (line*line+line)/2 + 1 ) );
    }

    return 0;
}

2014年7月23日 星期三

uva 424 Integer Inquiry

實做加法的大數運算:

如果直接把讀到的數字做加法,需要考慮位數對應和擴增陣列大小的問題。

把所有讀到的數字反向,再做加法 => 位數直接對應,擴增大小只要往後面加數字即可。

輸出結果時,再反向回來即可。

注意:

1. 如果用 fgets 讀,會有 '\n',改用 scanf("%s") 可以避免這個問題。

2.  當新加的數字位數比目前的 sum 多,或是兩個數字相加後,超過目前的位數時,需要對

    sum 擴增,因為 sum 擴增的那一位的值 0,跟原本兩個字元做相加的運算不同,所以要寫

   判斷式處理。

   ex :

   num[10]={0};

   假設現在 num 讀到 956 (第一個數字)

   下一個數字為 956

      659
    +659
________
      2191
            ↑ 在 num 裡原本的值是 0,如果依照前面字元 num[i]+= '9' - '0' + carry 的方法處理,

               在 if( num[i] > '9' ) 判斷進位的地方會有問題,所以遇到原本的值為 0 時,直接把値

               存進去 num[i] = carry + '0'
       6
     +05
________
       65
         ↑ 這個情況也是,原本的值是 0,直接把直存進去 num[i] = num_tmp[i] + carry



#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void reverNum(char number[]){
    char tmp[150]={0};
    int i,j;

    for(i=strlen(number)-1,j=0;i>=0;i--,j++){
        tmp[j]=number[i];
    }
    tmp[j]='\0';

    for(i=0;tmp[i]!='\0';i++){
        number[i]=tmp[i];
    }

    return;
}

int main(void){
    char number[150]={0},number_tmp[150]={0},carry;
    int i,top;

    top=-1;

    fgets(number,150-1,stdin);
    number[strlen(number)-1]='\0';
    reverNum(number);

    while( fgets(number_tmp,150-1,stdin)!=NULL ){
        if( strlen(number_tmp)==2 && number_tmp[0]=='0' ){
            break;
        }
        number_tmp[strlen(number_tmp)-1]='\0';
        reverNum(number_tmp);

        carry=0;
        for(i=0;number_tmp[i]!='\0';i++){
            if(number[i]==0){
                number[i] = number_tmp[i] + carry;
            }else{
                number[i] += (number_tmp[i]-'0') + carry;
            }

            if(number[i] > '9'){
                carry=(number[i]-'0')/10;
                number[i] = ( (number[i]-'0') % 10 ) + '0';
            }else{
                carry=0;
            }
        }

        while(carry!=0){
            if(number[i]==0){
                number[i]=carry+'0';
            }else{
                number[i]+=carry;
            }

            if(number[i] > '9'){
                carry=(number[i]-'0')/10;
                number[i] = ( (number[i]-'0') % 10 ) + '0';
            }else{
                carry=0;
            }

            ++i;
        }
    }

    reverNum(number);

    printf("%s\n",number);

    return 0;
}

2014年7月22日 星期二

uva 10041 Vito's Family

一看到題目時,會想說把 street number 全加起來後算總共相異 street number 個數的平均,

但是取 street number 的中位數所得的 sum 會更少。

平均數為這些 street number 的中心,和左、右的 street number的差異在 +1 ~ -1 之間,但

是題目有說 "會有相同的 street number",平均數左、右兩邊的 street number 個數不相同,

加總起來時,會因為相同的 street number,而造成差異。

中位數的兩邊的 street number 個數都一樣,即使完全相異的 street number 也可以處理。

ex: 2, 3, 10

mean : 5   =>   2, 3, 5, 10

5 向左、右兩邊走時,都要走 d(3,5), d(3,10)

median : 3 => 2, 3, 10

往右走時,會走 d(3,10)

d(3,10) < d(3,5) + d(3,10)

當數字有出現相同時,中位數的某一邊 street number 個數有可能比較多,造成 sum 增加。

因此,取中位數所得的 sum 會比較小。


#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int compare(const void* a , const void* b){
    return *(int *)a - *(int *)b;
}

int main(void){
    int amount,i;
    int relatives,streets[510],sum,median;

    scanf("%d",&amount);
    while(amount--){
        scanf("%d",&relatives);
        for(i=0;i<relatives;i++){
            scanf("%d",&streets[i]);
        }

        qsort(streets,relatives,sizeof(int),compare);

        median=streets[relatives/2];

        sum=0;
        for(i=0;i<relatives;i++){
            sum+=abs(streets[i]-median);
        }

        printf("%d\n",sum);
    }



    return 0;
}

2014年7月16日 星期三

uva 657 The die is cast

解析圖 (travel graph),實作時,比較難判斷的是遇到的 "X" 是否是和其他 "X" 相連,可能是從

其他方向走道 "X",但是這是和之前走過的 "X" 相連。
 
我用的是兩個不同功能的 DFS,一個是用來把相連的 " *" 走完,一個是用來走完相連的一組

"X",因為相連的 "X",代表要被計算的點數值 1,但是走過的 "X" 要標上 "*",前一個 DFS 才

能把這面 dice 走完。一次直接把連接的 "X" 走完,那下次遇到的 "X" 一定不是和之前遇到的

"X" 相連的,會比較好判斷。


test input:
3 2
XX*
X..
0 0

test output:
Throw 1
1
(newline)

(test input , output from : http://acm.uva.es/board/viewtopic.php?f=7&t=1948&hilit=657&sid=e5ead96b6830e0b0e7baed52294a391e&start=30#p204733)


#include <stdio.h>
#include <stdlib.h>

int counter;
int w,h;
char dice[60][60]={0};

void DFS_X(int x,int y){
    if(dice[x][y]!='X') return;

    dice[x][y]='*';

    DFS_X(x+1,y);
    DFS_X(x,y+1);
    DFS_X(x-1,y);
    DFS_X(x,y-1);

    return;
}

void DFS(int x, int y){
    if(dice[x][y]!='*' && dice[x][y]!='X') return;


    if(dice[x][y]=='X'){
        ++counter;
        DFS_X(x,y);
    }

    dice[x][y]='.';

    DFS(x+1,y);
    DFS(x,y+1);
    DFS(x-1,y);
    DFS(x,y-1);

    return;
}

int compare(const void*a, const void*b){
    return (*(int*)a)-(*(int*)b);
}

int main(void){
    int i,j;
    int num[100],top,cases=0;
    char c;

    while(scanf("%d%d%c",&w,&h,&c)==3){
        if(!w&&!h) break;

        for(i=1;i<=h;i++){
            for(j=1;j<=w;j++){
                scanf("%c",&dice[i][j]);
            }
            scanf("%c",&dice[i][j]);
        }

        top=-1;
        for(i=1;i<=h;i++){
            for(j=1;j<=w;j++){
                if(dice[i][j]=='*' || dice[i][j]=='X'){
                    counter=0;
                    DFS(i,j);
                    num[++top]=counter;
                }
            }
        }
        qsort(num,top+1,sizeof(int),compare);

        printf("Throw %d\n",++cases);
        for(i=0;i<top;i++){
            printf("%d ",num[i]);
        }
        printf("%d\n\n",num[i]);


    }


    return 0;
}