2012年1月13日 星期五

acm 10963

#include <stdio.h>
#include <math.h>
int main()
{
  int i,data,a,y1,y2,temp,first=0;
 
  while(scanf("%d",&data)==1)
  {   
      
     int flag =1; 
     data--; 
     if(first)
        printf( "\n" );
     first++;
     scanf("%d",&a);    
     scanf("%d %d",&y1,&y2);
     temp= abs(y1-y2);
    
     for(i=0;i<a;i++)
     {
       scanf("%d %d",&y1,&y2);             
       if(abs(y1-y2)!=temp)
          flag=0;            
     }
    
     if(flag)
       printf("Yes\n");
     else                   
       printf("No\n");                   
  } 
     
 system("pause");
 return 0;   
}

acm 10929 You can say 11

 [心得]
    if((abs(odd-even))%11==0)  ,(abs(odd-even)) 記得要括弧,不然會一直錯!


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

char s[1002];

int main()
{
  while(gets(s))
  {
    int i,length,num;
    int odd=0,even=0;
    if(s[0]=='0'&& s[1]=='\0')
      break;
   
    length =strlen(s);               
    for(i=0;i<length;i++)
    {              
      if((i%2)== 1) /*奇數位元*/
        odd += s[i]-48;
      else        /*偶數位元*/
        even+= s[i]-48;                         
    }
  
    if((abs(odd-even))%11==0)
      printf("%s is a multiple of 11.\n",s);
    else 
      printf("%s is not a multiple of 11.\n",s);        
                   
  } 
 
 system("pause");
 return 0;   
}

acm 10924 Prime Words

[心得] //0.004

#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
  char s[30];
  int ans[53];
  int i,length,sum,flag;
   
  while(gets(s)!=NULL)
  {
     memset(ans,0,sizeof(ans));               
     length =strlen(s);
     sum=0;
     flag=0;                  
     for(i=0;i<length;i++)
     {
       if(isupper(s[i]))
          ans[(s[i]-38)]+=1;  /* 大寫A ASCII從65map到陣列ans27的位置 */
       else  
          ans[(s[i]-96)]+=1;  /* 小寫a ASCII從97map到陣列ans1的位置 */             
     } 
     for(i=1;i<53;i++)
     {            
       if(ans[i])
          sum=sum+ans[i]*i;                  
     }
     for(i=2;i<sum;i++)
     {
       if(sum %i ==0)
          flag=1;                    
     }
     if(flag)
       printf("It is not a prime word.\n");
     else 
       printf("It is a prime word.\n");
                      
  }   
  system("pause");
  return 0;   
}

acm 10903 Rock-Paper-Scissors Tournament

[心得] //0.256

1.memset也可以初始化 布林陣列 ,memset define 在 "string.h"裡
2. res[]陣列是用來記錄選手i贏的次數
3.flag[]陣列是,表示這次比賽如果不是平手,=>用來記錄選手i 這次比賽有意義
4, time[] 陣列是用來紀錄選手i到底比賽幾次(但是平手不紀錄)

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
 
int i,j=0,number,time[150],game,p1,p2,res[150];
char m1[10],m2[10];

int main()
{

  while(scanf("%d %d",&number,&game)==2)
  {
                 
     if(number==0)
        break;
     if(j>0)
        printf("\n");
     j++;
    
     bool flag[number+1];
     game= game*number*(number-1)/2;
     memset(res,0,sizeof(res));
     memset(time,0,sizeof(time));
     memset(flag,false,sizeof(flag));
    
     for(i=0;i<game;i++)
     {
    
      scanf("%d %s %d %s",&p1,m1,&p2,m2);
        
       if(m1[0]=='r' && m2[0]=='p') 
           {res[p2]+=1; flag[p1]=flag[p2]=true; time[p1]+=1;time[p2]+=1;}
       else if (m1[0]=='r' && m2[0]=='s')  
           {res[p1]+=1; flag[p1]=flag[p2]=true; time[p1]+=1;time[p2]+=1;} 
       else if (m1[0]=='p' && m2[0]=='r')   
           {res[p1]+=1; flag[p1]=flag[p2]=true; time[p1]+=1;time[p2]+=1;}
       else if (m1[0]=='p' && m2[0]=='s')    
           {res[p2]+=1; flag[p1]=flag[p2]=true; time[p1]+=1;time[p2]+=1;;}
       else if (m1[0]=='s' && m2[0]=='p')    
           {res[p1]++;  flag[p1]=flag[p2]=true; time[p1]+=1;time[p2]+=1;}
       else if (m1[0]=='s' && m2[0]=='r')
           {res[p2]+=1; flag[p1]=flag[p2]=true; time[p1]+=1;time[p2]+=1;}
    
     }
     for(i=1;i<=number;i++)
     {
        if( flag[i] == false)
           printf("-\n");
        else
        {                    
           printf("%.3f\n",(double)res[i]/time[i]);
        }
     } 
  } 

  system("pause");
  return 0;   
}

2012年1月11日 星期三

acm 10878: Decode the tape

[心得] 0.008

1. ,每行都是一個ASCII 碼,每行只要注意 'o'出現的位置,轉換成相對應的ASCII碼

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

int main()
{

   int length,i,sum,counter=0;
   char s[20];
   char output[100000];
  
       gets(s);
       
       while(gets(s)!=NULL)
       {  
          if(strcmp(s,"___________")==0)
            break;
         sum=0;
       /*  for(i=0;i<=11;i++)
         printf("s[%d]=%c\n",i,s[i]);*/
      
          for(i=0;i<=11;i++)
          {  
              if(s[i]=='o')
              {
                  if((9-i)==0)
                    sum =sum+1;
                  else if((9-i)==1)
                    sum =sum+2;
                  else if((9-i)==2) 
                    sum =sum+4;
                  else 
                    sum = sum+pow(2,(8-i));
                     
              } 
          
          }
             /*printf("%c\n",sum); */
             output[counter]=sum;
             counter++;
                         
       } 
      
        for(i=0;i<counter;i++)
           printf("%c",output[i]); 
        /*counter=0; 
        printf("\n");*/

   system("pause");
   return(0);   
}

acm 10812: Beat the Spread!

[[心得]  0.004

#include <stdio.h>

int main()
{
  int a,b,data;

  while(scanf("%d",&data)==1)
  {
       int k;                          
       for(k=0;k<data;k++)
       {
           int x,y;      
           scanf("%d %d",&a,&b);
           if(b>a||(a+b)%2!=0)
              printf("impossible\n");  
           else
           {
              x = (a+b)/2;
              y = a-x;
              if(x<0||y<0)
                 printf("impossible\n"); 
              else
                 printf("%d %d\n",x,y);                             
           }  
       }                 
  }
   
   
  system("pause");
  return 0;   
}

acm 10789: Prime Frequency

[心得] 0.004 
用一個MAP(255 ASCII 最大好像255)陣列,存每個字母出現次數,  如果出現次數大於2才需要判斷(用暴力法判斷是否為質數) ,1非質數

#include <stdio.h>
#include <stdbool.h>

int record;
bool isprime(int temp)
{
  int k;
  for(k=2;k<temp;k++)  
  {                  
      if(temp%k==0)
      {
         return false;
      }  
  }
  record =1;
  return  true;   
}
int main()
{

  int data,i,length,counter=0;
  bool flag= false;
 
  scanf("%d",&data);
  scanf("\n");
  while(data)
  {

     char s[2002];
     while(gets(s)!=NULL)
     {   
              
         int map[256]={0};
         record=0;
         data--;   
         counter++;
         length =strlen(s);
         printf("Case %d: ",counter);
        
         /*for(i=0;i<length;i++)
           printf("s[%d]= %c\n",i,s[i]);*/
        
         for(i=0;i<length;i++)
             map[s[i]]++; 
        
         /*for(i=0;i<255;i++)
           printf("map[%d]= %d\n",i,map[i]); */
                                     
         for(i=0;i<255;i++)                
         {
             if(map[i]>=2)                             
                flag = isprime(map[i]);
             if(flag)
             {
                printf("%c",i);
                flag =false;
             }
          }
          if(!record)
             printf("empty\n");
          else
             printf("\n"); 
      }                   

  }
   
   
 system("pause");
 return 0;   
}

acm 10783: Odd Sum

[心得]  0.004
判斷奇數 ,照題目說的做就好了

#include <stdio.h>
int main()
{
   int data;
   int a,b,i,sum=0,counter=1;
   scanf("%d",&data);
   while(data)
   {   
       int sum =0;                
       scanf("%d %d",&a,&b);
       for(i=a;i<=b;i++)
       if(i%2==1)
         sum = sum+ i;               
       printf("Case %d: %d\n",counter,sum);                           
       counter++; 
       data--;
                 
   }
   
  system("pause");
  return 0;
}

acm 10696: f91

[心得] //0.091

#include <stdio.h>

 
int f91( int a)
{
  if(a<=100)
   {
      return f91(f91(a+11));
   }
  else
  {
   
     return (a-10);
  } 
  
}

int main()
{
  int a,b;
 
  while(scanf("%d",&a)==1)
  {
                         
     if(a==0)   
      break;
       b=a;
       b=f91(b);
       printf("f91(%d) = %d\n",a,b);
                     
  }
      
  system("pasue");
  return 0;
    
}

C acm10673 Play with Floor and Ceil

對任何2個整數 x 和 k,存在另2個整數 p 和 q 使得:

要證明上面的式子是一件相當容易的事,所以我們不會要求你去做。我們要你做的事甚至更容易一些。給你 x 和 k 的值,請你找出 p 和 q 使得上面的式子成立
對每組測試資料輸出一列,含2個整數 p 和 q 。假如存在不只一組答案,輸出任何一個都可以。

 [心得] 0.340

1. % (mod)只能用int ,所以變數宣告為double,運算時必須type casting 成int 型態
2. Solution
  
CASE:(整除) 
  中floor 和ceiling 相同(表示x/k可整除),
     ==> 等號兩邊同乘k
  ==> kx= px+qx;
     ==> k=p+q; (最簡單的方式,令p為0, k=q)


CASE : (差 1)
  中floor 和ceiling差1,
  最簡單的解,令p=-x, q=x;

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

int main()
{
  long int x,k,p,q;
  int i,n;

  scanf("%d",&n);
  while(n)
  {
    
     for(i=0;i<n;i++)
     {
        scanf("%ld %ld",&x,&k);
        if( (int)x%(int)k ==0)
        {
            p=0; q=k;
        }
        else /*floor(x/k) ceil(x/k) 差 1*/
        {    
           p=(0L-x);
           q=x;
        }
        printf("%ld %ld\n",p,q);               
     }
     n--;              
 
  } 
  system("pause");
  return 0;   
}

2012年1月10日 星期二

acm 10589 Area

[心得]  0.096

1.一開始就有注意到 int 最好不要和 浮點數比較的問題,所已全部變數宣告成double
   這樣在DEV C++裡雖然答案是對的 但是送上去會得到WA,所以只好參考網路上別人的答案把int 運算都 type casting 成double,才AC!
2.每個點與ABCD 的距離都小於半徑!



#include <stdio.h>


int main()
{
  
   int a,n;
   while(scanf("%d %d",&n,&a)==2)
   { 
      if(n==0 &&a==0)
         break;            
      int i,counter=0;            
      double x,y;
      for(i=0;i<n;i++)
      {
          scanf("%lf %lf",&x,&y);
          if((x*x)+(y*y)<= (double)a*a&&
             (a-x)*(a-x)+(y*y)<=(double)a*a&&
             (a-x)*(a-x)+(a-y)*(a-y)<=(double)a*a&&
             (x*x)+(y-a)*(y-a)<=(double)a*a)
             counter++;
             
      }
     
      printf("%.5lf\n",((double)counter/(double)n*(double)a*(double)a));             
   }
    return 0;
}

2012年1月9日 星期一

acm 10550 Combination Lock

[心得] 0.008
1.順時針轉鎖,但是實際上轉盤是逆時針轉
   假設輸入a b c d四個數字:
  a->b 是順時鐘轉, (轉盤實際是逆時針轉)
           case : a>b (a-b)*9
           case :a<b  (40-b+a)*9

  b->c 是逆時針,(轉盤實際是順時針轉)
           case : b>c (40-b+c)*9
           case:  b<c (b-c)*9
  c->d 同 a->b

#include <stdio.h>

int angle(int x,int y)
{
    if(x<y)
       return((40+x-y)*9);
    else
       return ((x-y)*9);
}


int angle_rev(int x,int y)
{
    if(x<y)
       return ((y-x)*9);
    else
       return((40-x+y)*9); 
}
int main()
{
  int a,b,c,d;
 
  while( scanf("%d %d %d %d",&a,&b,&c,&d)!=EOF)
  {
     int angle_a=1080;   
    if(a==0&&b==0&&c==0&&d==0)
      break;
    
    angle_a+=angle(a,b)+angle_rev(b,c)+angle(c,d); 
    printf("%d\n",angle_a); 
 
  }   
  system("pause");
  return 0;   
}

acm 10499 The Land of Justice

[心得] 0.036
球體表面積公式為 4*π*R*R
1.如果切成 一半,可以想像多兩個大圓面積 為2*(R*R*π)
    ==>2*(R*R*π) /4*π*R*R =50%
 2.如果球體等分成3塊, 表面積會多 6*(1/2*R*R*π)  (想像每個切面都是1/2個大圓面積)
    ==>3*(R*R*π) /4*π*R*R =75%
 3.如果球體等分成3塊, 表面積會多 8*(1/2*R*R*π)
    ==>4*(R*R*π) /4*π*R*R =100%



#include <stdio.h>

int main()
{
   long long int number;
   while(scanf("%lld",&number)!=EOF)
   {
      if(number <0)
         break;                            
      if(number == 1) 
         printf("0%%\n");
      else
         printf("%lld%%\n",25*number);          
   }
  system("pause");
  return 0;
}

acm 10473: Simple Base Conversion

 [心得] :0.012
1.題目說這個數10進位的值一定小於 231 
   所以可以用2的31次方數值試看看
 2.用long long int宣告 scanf 記得用%lld

3. (網路上別人寫的文章)
字串轉數字
int nValue;
float fValue;
CString szValue = "224";
sscanf(szValue,"%d",&nValue);
szValue = "5.82";
sscanf(szValue,"%f",&fValue);
以上為sscanf()的用法
第一個參數為我們所要轉換的字串
第二個參數則是該字串的格式 如果我們要將他轉成整數 則裡面就是"%d"
如果是要轉浮點數 裡面就是"%f"
轉好的結果就會放在第三個參數所指的位置裡面
特別要注意 第三個參數是要傳入指標 不是傳入數值

#include <stdio.h>

int main()
{
   char a[4000];
   long long int number;
   while(gets(a)!=NULL)
   {
     if(a[0]=='-') break;
    
     if(a[1]=='x')
     {
       sscanf(a,"%x" ,&number),
       printf("%lld\n", number);  
     }
     else
     {
        sscanf(a ,"%lld" ,&number),
        printf("0x%X\n", number);  
     }        
   }
  system("pause");
  return 0;
}

2012年1月8日 星期日

acm 10370

 [心得]  0.016
1, answer[answer_count]=(double)100/num*counter;
    一開始寫成answer[answer_count]=(double)(100/num)*counter,小數點後都是0,要注意
2.num 一開始為了方便宣告成double,結果連續scanf()一直有問題,要宣告成int
3. printf("%.3lf%%\n", answer[i]); 注意印出百分比 %% 要寫兩個

#include <stdio.h>
int main()
{
  int i,data,counter,answer_count=0;
  int score[3000],sum,num;
  double answer[3000];
  double average;
  scanf("%d",&data);
  while(data)
  { 
     sum=0; counter=0;
     scanf("%d",&num);

     for(i=0;i<num;i++)
     {  
        scanf("%d",&score[i]);
        sum=sum+score[i];
     }    
     average = sum/num;
     for(i=0;i<num;i++)
     {
        if(score[i]>average)
        counter++;
     }
     answer[answer_count]=(double)100/num*counter;
     answer_count++;
     data--;   
    
  } 
    for(i=0;i<answer_count;i++)
    {
       printf("%.3lf%%\n", answer[i]);
    }
   
  /*system("pause");*/
  return 0;   
}

acm 10340 All in All

[心得]  0.24
原來我題目看錯了!XD 頭昏!
VERDI vivaVittorioEmanueleReDiItalia YES
我前面兩個寫的都是比對要完全相同才行 t裡的字串要完全相同才判斷正確,
其實不用只要 當你移走t字串中的某些字元後,剩下的字串就是s。就可以了!
也就是 s在t中不需要完全相連!

#include <stdio.h>
#include <string.h>
#include <stdbool.h>
int main()
{
  char s[1000000],t[1000000]; 
  int i,j,counter;
  bool flag = false;
  int temp;
  int length;
  while(scanf("%s %s",s,t)!=EOF)
  {
 
    int t_length = strlen(t);
    int s_length = strlen(s);
    j=0;
    for(i=0;i<t_length;i++)
    {     
       if(t[i]==s[j]&& j<s_length)
       {  
            j++;
            if(j==s_length)
           {
                flag = true;
                i=t_length;
                break;
           }
                               
       }
               
    }                    

     if(flag)
     {
       flag = false;
       printf("Yes\n");
     }
     else
       printf("No\n");            
  }
  system("pause");
  //return 0;   
}



[心得] WA 不知道邏輯哪裡錯了!有空再看!
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
int main()
{
  char s[1000000],t[1000000]; 
  int i,j,counter;
  bool flag = false;
  int temp;
  int length;
  while(scanf("%s %s",s,t)!=EOF)
  {
 
    counter=0;
    int t_length = strlen(t);
    int s_length = strlen(s);
    for(i=0;i<t_length;i++)
    {    j=0;
         temp=i;
         counter =0;
       while(t[temp]==s[j]&& j<s_length)
       {  
           temp++;
           j++;
           counter++;
           if(counter==s_length)
           {
                flag = true;
                i=t_length;
                break;
           }
                               
       }
               
    }                    

     if(flag)
     {
       flag = false;
       printf("Yes\n");
     }
     else
       printf("No\n");            
  }
  system("pause");
  //return 0;   
}


[心得] WA
不懂為什麼用 strstr判斷 會WA,只好重寫一支,不知道是否於字串超長有關係!
剛剛GOOGL了一下, 使用 strstr的確有長度限制!

#include <stdio.h>
#include <string.h>
int main()
{
  char s[100000],t[100000];
  while(scanf("%s %s",s,t)!=EOF)
  {
    int length,comp;
    char *pos;  
    pos = strstr(t,s);
    if(pos!=NULL)
      printf("YES\n");   
    else
      printf("NO\n");
           
  } 
   
 system("pause");
 return 0;
}

acm 10300 Ecological Premium

[心得]  0.004

1.double 要用lf

#include <stdio.h>
int main()
{
  int i,counter,data; 
  double award,answer[21];
  counter=0;
  scanf("%d",&data);
 
  while(data)
  { 
    double a,b,c;
    int famer;
    data--;
    award=0;
  
             
    scanf("%d\n",&famer);
    for(i=0;i<famer;i++)
    {
                    
       scanf("%lf %lf %lf",&a,&b,&c);
       award = award+a*c;                
    }  
    answer[counter]= award;
    counter++;                  
                         
  }   
    for(i=0;i<counter;i++)
      printf("%.0f\n",answer[i]);
   system("pause");
   //return 0;
}

ACM Solved 20 Ranking17159

ACM 10222 Decode The Mad Man

[心得] :0.004
1. ACM 10082 WERTYU差不多
2.注意大寫要轉換成小寫
3.\ 要打成\\ 上次打錯   XD!

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

int main()
{
 int c;
 char *pos;  
 char key[]="1234567890-=qwertyuiop[]\\asdfghjkl;'zxcvbnm,./";
 while((c=getchar())!=EOF)
 {       
    if(isupper(c))
       c= tolower(c);        
    pos= strchr(key,c);         
    putchar((pos)?key[pos-key-2]:c);                     
 }

 system("pause");
 //return 0;   
}

ACM 10209 Is This Integration ?

[心得] :0.044



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

#define PI  2.0*acos(0.0)
#define line_area(r)  (r) * (r) * (1  + PI * 1.0 / 3.0 - sqrt(3))
#define point_area(r) (r) * (r) * (-4 + PI * 1.0 / 3.0 + sqrt(3) * 2)
#define square_area(r) (r) * (r) * (4  - PI * 2.0 / 3.0 - sqrt(3))

int main()
{
   double a;
   while(scanf("%lf",&a)==1)
   {
     printf("%.3lf %.3lf %.3lf\n",line_area(a),point_area(a),square_area(a));
   }

  system("pause");  
 // return 0;
}

ACM 10041 Request for Proposal

 [心得]: //0.008
1.scanf()如果遇到名字有空白,就會有問題,所以用gets()
 2. 比較需要注意的是 scanf() 後面接 gets(),gets()會多讀一個'\n',所以第二個 gets(nothing)的
    for 迴圈,counter 從0開始!
3.只要注意廠商名稱和價錢,提共的項目數量,對於項目名稱可以不用理會!
      for(i=1;i<=n;i++)
           gets(nothing);
4.ACM的格式如果沒搞清楚,就會WA,但是比較高興的是,現在自己想和寫出來的Code終於比較
   少WA了! 可以很快就AC!


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

struct Corp
{
  char name[90];
  float money;
  int supply;     
         
};
struct Corp Answer,Temp;

int main()
{  
    int i,n,p,q=0;
    char output[1001][90];
    char nothing[90];
    while(scanf("%d %d",&n,&p)==2)
    {
        if(n==0 || p==0)
            break;
        gets(nothing);
        int counter=0;
        Answer.supply=0;           
        for(i=1;i<=n;i++)
           gets(nothing);
                               
        while(gets(Temp.name)!=NULL)
        {
                                    
            if(isalpha(Temp.name[0]))
            {
              counter++;                         
              scanf("%f %d",&Temp.money,&Temp.supply);
              /*printf("%s\n",&Temp.name);
              printf("%f %d\n",Temp.money,Temp.supply);*/
              for(i=0;i<=Temp.supply;i++)
                 gets(nothing);
              if(Temp.supply > Answer.supply || (Temp.supply == Answer.supply && Temp.money < Answer.money))
              {
                 strcpy(Answer.name,Temp.name);
                 Answer.supply =  Temp.supply;
                 Answer.money = Temp.money;
                      
              }
          
                            
            }
             if(counter == p)
              break;     
         
        }
       strcpy(output[q],Answer.name);
       q++;
                   
    } 
    for(i=0;i<q;i++)
    {
        if(i!=0) printf("\n");      
        printf("RFP #%d\n%s\n",i+1,output[i]);
    }
  
    
 system("pause");
 //return 0;   
}

2012年1月7日 星期六

C ctype.h

C 語言標準函數庫分類導覽 - 字元測試 ctype.h

標頭檔 ctype.h 宣告許多跟字元測試相關的函數,例如有測試字元是否為數字、字母、空格等等,另有將英文大小寫轉換的函數,這些函數都是以 int 型態為預設回傳值及參數的資料型態。



以下為字元測試的函數
函數名稱功能函數原型
isdigit測試字元是否為數字int isdigit(int);
isalpha測試字元是否為字母int isalpha(int);
isalnum測試字元是否為數字或字母int isalnum(int);
isxdigit測試字元是否為十六進位數字int isxdigit(int);
islower測試字元是否為小寫字母int islower(int);
isupper測試字元是否為大寫字母int isupper(int);
isascii測試字元是否為 ASCIIint isascii(int);
isblank測試是否為空白字元int isblank(int);
isspace測試字元是否為空格int isspace(int);
iscntrl測試是否為控制字元int iscntrl(int);
ispunct測試是否為空格、數字、字母以外的可列印字元int ispunct(int);
isprint測試是否為含括空格以內的可列印字元int isprint(int);
isgraph測試是否為空格以外的可列印字元int isgraph(int);


以下為英文字母大、小寫轉換的函數
函數名稱功能函數原型
tolower將大寫字母轉換為小寫int tolower(int);
toupper將小寫字母轉換為大寫int toupper(int);

string.h 字串操作

網路上別人寫好的文章,寫的很詳細!很適合作備忘錄! 

附上原文網址:http://pydoing.blogspot.com/2010/07/c-stdstring.html

C 語言標準函數庫分類導覽 - 字串處理 string.h

標頭檔 string.h 宣告許多字串處理相關的函數,包括拷貝、相接、搜尋、測試相等、計算長度等。


以 str 起頭的函數作為處理字串之用,另有以 mem 起頭的函數,這些函數則可以進行記憶體區塊的操作。 size_t 作為 sizeof 運算子的回傳型態,實際上可能為 unsigned int 或 unsigned long 。


以下函數可以拷貝字串
函數名稱功能函數原型
strcpy將字串 s2 拷貝到 s1char *strcpy(char *s1, const char *s2);
strncpy將字串 s2 最多 n 個字元拷貝到 s1char *strncpy(char *s1, const char *s2, size_t n);


以下函數可以將字串相接
函數名稱功能函數原型
strcat將字串 s2 接到 s1 的尾端char *strcat(char *s1, const char *s2);
strncat將字串 s2 最多 n 個字元接到 s1 的尾端char *strncat(char *s1, const char *s2, size_t);


以下函數測試兩個字串是否相等
函數名稱功能函數原型
strcmp比較 s1 與 s2 兩個字串是否相等int strcmp(const char *s1, const char *s2);
strncmp比較 s1 與 s2 兩個字串前 n 個字元是否相等int strncmp(const char *s1, const char *s2, size_t n);


以下函數作為字串的搜尋處理之用
函數名稱功能函數原型
strchr回傳在字串 s 中,字元 c 第一次出現位置的指標char *strchr(const char *s, int c);
strcspn計算經過幾個字元會在字串 s1 中遇到屬於 s2 中的字元size_t strcspn(const char *s1, const char *s2);
strspn計算經過幾個字元會在字串 s1 中遇到不屬於 s2 中的字元size_t strspn(const char *s1, const char *s2);
strpbrk回傳在字串 s2 中的任何字元在 s1 第一次出現位置的指標char *strpbrk(const char *s1, const char *s2);
strrchr回傳在字串 s 中,字元 c 最後一次出現位置的指標char *strrchr(const char *s, int c);
strstr回傳在字串 s2 在 s1 第一次出現位置的指標char *strstr(const char *s1, const char *s2);
strtok以字串 s2 的內容切割 s1char *strtok(char *s1, const char *s2);


以下函數計算字串的長度
函數名稱功能函數原型
strlen計算字串的長度size_t strlen(const char *s);


以下函數為進行記憶體區塊操作之用
函數名稱功能函數原型
memcpy從 s2 所指向的資料複製 n 個字元到 s1void *memcpy(void *s1, const void *s2, size_t n);
memmove從 s2 所指向的資料複製 n 個字元到 s1void *memmove(void *s1, const void *s2, size_t n);
memcmp比較 s1 與 s2 前 n 個字元的資料int memcmp(const void *s1, const void *s2, size_t n);
memchr找出字元 c 在 s 前 n 個字元第一次出現的位置void *memchr(const void *s, int c, size_t n);
memset將 s 中前 n 個字元全部設定為 cvoid *memset(void *s, int c, size_t n);


字串的宣告
  一般只要是用 " 符號所包起來的字元就是字串,如下的宣告
  char s[5]="abcd";
  字串"abcd"除了四個字元所佔的空間外還包含一個'\0'字元在最後面當字串結束符號
  所以總字元數是5
  字串就是一連續字元的最末端以一個'\0'字符做為結束的連續字元
  編譯器對字串的處理以及字串相關的函式,都是依照這個規格在處理字串,這也是字串與一般字元陣列不一樣的地方
  你也可以這樣子來宣告char s[]="abcd";
  雖沒有指明陣列索引值,但編譯器會自動幫你補上,所以陣列 s 將會是一個索引值為 5 的陣列

字串與char*
  以下是一個最簡單的應用
  char s[]="abcd";
  char* p=s;
  p 就相當於是一個指著 s 的指標

  char* str="abcd";
  指標str相當於是一個字串,編譯器會自動配置一塊空間擺放"abcd"這個字串,然後讓str指標指向
  但他和char s[]是不一樣的地方,是你不能修改那塊空間裡的值,像這樣 *str='z';
  但你能再讓他指向別的地方

字串的處理
  C裡頭有一組現成的專用拿來處理字串的函式,需引入 string.h 這個標頭檔
  以下簡單的介紹這些常用的函式

  size_t strlen(const char* source)
    取得字串長度
   
  char* strcpy(char* destn,const char* source)
    拷貝字串,將source字串拷貝至destn的空間,回傳值其實就是destn的位置
   
  char* strncpy(char* destn,const char* source,size_t n)
    拷貝字串,將source字串的前n個字元拷貝至destn的空間,回傳值為destn的位置
   
  char* strcat(char* destn,const char* source)
     拷貝字串,將source字串串接至destn字串後面,回傳值為destn的位置,請確定destn的空間足夠儲放串接後的字串
   
  char* strncat(char* destn,const char* source,,size_t n)
    串接兩字串,將source的前n個字串串接至destn字串後面,回傳值為destn的位置,請確定destn的空間足夠儲放串接後的字串
   
  int strcmp(const char* str1,const char* str2)
    比對字串,若完全相等則回傳0,若有差異,回傳其字元值差
   
  int strncmp(const char* str1,const char* str2,size_t n)
    比對字串只比對前n個字元,若完全相等則回傳0,若有差異,回傳其字元值差
   
  int strcasecmp(const char* str1,const char* str2)
    忽略大小寫比對字串,比對字串,若完全相等則回傳0,若有差異,回傳其字元值差
   
  int strncasecmp(const char* str1,const char* str2,size_t n)
    忽略大小寫比對字串只比對前n個字元,若完全相等則回傳0,若有差異,回傳其字元值差

  char* strchr(const char* str,int ch)
    找出字串中第一個指定字元的位置,若找不到傳回0
   
  char* strrchr(const char* str,char ch)
    找出str字串中,最後一個出現ch字元的字元,回傳該字元位址
    char str[]="123123";
    strrchr(str,'1');
    回傳值將會是&str[3]
   
  size_t strcspn(const char* str,const char* reject)
    傳回str字串中第一個不含reject字串中字元的前字元數
    char str[]="ABCD123456789";
    strcspn(str,"4321");
    將會得到4
   
  char* strdup(const char* string)
    複製字串,其字串空間是使用molloc()所配置,事後也能用free()釋放掉,失敗回傳NULL
   
  char* strfry(char* string)
    隨機重組字串內的字元
   
  char* strpbrk(const char* str,const char* accept)
    找出str字串中,有accept字串中字元的字元,回傳該字元的位址
    char str[]="ABCD123456789";
    strpbrk(str,"4321");
    回傳值將會是&str[4]
   
  char* strrchr(const char* str,char ch)
    找出str字串中,最後一個出現ch字元的字元,回傳該字元位址
    char str[]="123123";
    strrchr(str,'1');
    回傳值將會是&str[3]
   
  size_t strspn(const char* str,const char* accept)
    傳回str字串中前面含有accept字串中字元的字元數
    char str[]="ABCD123456789";
    strspn(str,"BA");
    將會得到2
   
  char* strstr(const char* str1,const char* str2)
    搜尋字串,在str1的字串搜尋str2字串,傳回搜尋到的子字串位址
   
  char* strtok(char* str,const char* delimit)
    分解字串,str字串為要被分解的字串,delimit為要做為分解依據的字串
    找到了要分解依據的字元便將其設為='\0',即回傳該字串
    第一次使用strtok()引數str必須指定,往後可設為NULL,如此將持續一直分解下去,直到回傳值為NULL,便不能再分解下去
    char str[]="abc def:ghi-xyz try"
    char* p;
    printf("%s=",strtok(str," :-"));
    while(p=strtok(NULL," :-"))printf("%s=",p);
    將印出 abc=def=ghi=xyz=try
 
  以上所例函式從較常用者先列出string.h不只有專用處理字串的函式,也有專門用來處理記憶體的相關函式
  它們的差別在於字串函式處理的對象是字串,也就是'\0'符號做為結尾的一串字元,所傳入的char*型別的參數都必須要是字串
  而記憶體函式是不管內容是什麼字元,都一視同仁處理

string.h - memchr,memset,memcmp,memapy,memmove

 memchr

Declaration:
vo

id *memchr(const void *str, int c, size_t n);
  搜尋mem記憶體內容的前n個字元是否有ch字元,回傳值為該ch字元的位址,若無則回傳0


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

int main()
{
  char s[]="I LOVE C and C++.";
  printf("%s\n",(memchr(s,'L',18)));
  printf("%s\n",(strchr(s,'L')));
 
  char bs[]="1111 1010 0101 1100 0011";
  printf("%s\n",(memchr(bs,'11',40)));
  printf("%s\n",(strchr(bs,'11')));


  char nulls[]="'\0' 1111 1010 0101 1100 0011";
  printf("%s\n",(memchr(nulls,'11',40)));
  printf("%s\n",(strchr(nulls,'11')));
 
 
  system("pause");
}

    RESULT:
    LOVE C and C++.
    LOVE C and C++.
    1111 1010 0101 1100 0011
    1111 1010 0101 1100 0011

   1111 1010 0101 1100 0011
   (null)  <=如果字串裡有null('\0') ,strchr一遇到 NULL就會停止 */


 
  memchr與strchr 不同的地方是
  strchr stops when it hits a null character but memchr does not;
  this is why the former does not need a length parameter but the latter does.

 




 memcmp

Declaration:
int memcmp(const void *str1, const void *str2, size_t n);

  記憶體比對,比對mem1和mem2所指的記憶體空間的前n個字元,回傳值為相異的字元差



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

int main()
{
  char s[]="LOVE C and C++";
  char t[]="LOVE Is A Clothes";
  printf("%d\n",(memcmp(s,t,4)));
  printf("%d\n",(memcmp(s,t,7)));
  printf("%d\n",(memcmp(t,s,7)));
 
  /*RESULT:
    0
    -1
    1   */
 
 
  system("pause");
}


memcpy

Declaration:
void* memcpy(void* destn,const void* source,size_t n)
    記憶體拷貝,從soutce中拷貝n個字元至destn,回傳值為destn位址
 

memccpy

void* memccpy(void* destn,const void* source,int ch,size_t n)
  記憶體拷貝,拷貝從ch出現以後的n各字元,從soutce中拷貝n個字元至destn,,並回傳出現ch字元的下一個字元的位址 若未出現ch字元則回傳0


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

int main()
{
  char s[]="123456789 I LOVE C and C++";
  char t[35];
  printf("memcpy result :%s\n",(memcpy(t,s,30))); 
  printf("memccpy result:%s\n",(memccpy(t,s,'I',30))); 
 
  /*RESULT:
    memcpy result :123456789 I LOVE C and C++
    memccpy result: LOVE C and C++
   
  */
 
  system("pause");




memmove

Declaration:
void *memmove(void *str1, const void *str2, size_t n);
Copies n characters from str2 to str1. If str1 and str2 overlap the information is first completely read from str1 and then written to str2 so that the characters are copied correctly. Returns the argument str1.
記憶體拷貝,從soutce中拷貝n個字元至destn,但destn和source的區域若有重疊,也能進行拷貝
 但執行效率比memcpy()略慢些

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

int main()
{
    char s[40] = ".............out of work";
    char t[20] = "future Job";
   
    memmove(s, t, 10);
   
    printf("%s\n", s);
    

 
  /*RESULT:
   future Job...out of work */
 
  system("pause");
}


memset

Declaration:
void *memset(void *str, int c, size_t n);
Copies the character c (an unsigned char) to the first n characters of the string pointed to by the argument str. The argument str is returned.

可以參考  memset那篇

The C Library Reference Guide (好用網站)

http://www.acm.uiuc.edu/webmonkeys/book/c_guide/index2.html



 

2012年1月6日 星期五

ACM 10107 What is the Median?

這篇作法參考 http://mypaper.pchome.com.tw/iustlovefish/post/1311934438

#include <stdio.h>

int main()
{
  int counter=0;
  int input[10001]={0};
  int a,i,j,temp=0;
      while(scanf("%d",&a)==1)
      {
         for(i=0;i<=counter;i++)
            if(input[i]>a)
              break;
         for(j=counter;j>i;j--)
           input[j]=input[j-1];
          input[j]=a;
          counter++;
      
       if(counter%2==0) printf("%d\n",((input[counter/2]+input[counter/2-1])/2));
       else printf("%d\n",input[counter/2]); 
        /*for(i =0;i<counter;i++)
          printf("data %d\t",input[i]); */
      }
    return 0;     
   system("pause");   
}

2012年1月5日 星期四

ACM 10082 WERTYU

 [心得] :0.004
 1.要注意空白和換行的處理
 2.如果是小寫,則不處理,直接輸出
#include <stdio.h>
#include <string.h>
int main()
{

    char key_board[] = "=-0987654321`\\][POIUYTREWQ';LKJHGFDSA/.,MNBVCXZ";
    char input[3000];
    char map[3000];
    int length1,length2;
    while(gets(input)!=NULL)
    {
      int i,j,counter=0;
      length1 = strlen(input);
      length2 = strlen(key_board);
     
      for(i=0;i<length1;i++)
      { 
           for(j=0;j<length2;j++)
          {  
            if (input[i] == 32)
            {
                   map[i]=32;
                   counter++;

            }  
            else if (input[i] == 13)
            {
                   map[i]=13;   
                    counter++;                
            }
            else if(input[i]==key_board[j])
           {
    
                 map[i]=key_board[j+1];
                  counter++;
           }
    
         }
         if( counter ==0)
           {
                map[i] =  input[i];

           }
           counter=0;
      }
        for(j=0;j<length1;j++)
        {
            printf("%c",map[j]);
        }
        printf("\n");
    }
    system("pause");   
    //return 0;
}


寫完之後看到網路上別人寫的,GOOD!
#include <stdio.h>
#include <string.h>
int main()
{
  char s[50]="=-0987654321`\\][POIUYTREWQ';LKJHGFDSA/.,MNBVCXZ"; 
  char *x;
  char c;
  while((c=getchar())!=EOF)
  {
      x=strchr(s,c);
      putchar(x?s[x-s+1]:c);             
  }
  system("pause");
  return 0;  
}

2012年1月4日 星期三

C acm10071 Back to High School Physics

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

int v,t,s;

int main()
{
     while(scanf("%d %d",&v,&t)==2)
     {
        s =2*v*t;
        printf("%d\n",s);              
     }  
   
 system("pause");
 //return 0;   
}

C acm 10062 Tell me the frequencies!

 [心得] : //0.012
1.他測資應該有1000個,char array[1001]; 一開始只設1000,一直RE
2.  
     if(first)
       printf("\n");
      first =1;  奇怪的印出空白,這是參考網路上前輩資料

3.要用gets ,用scanf會忽略空白



#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main()
{
  char array[1001];
  int first=0;

  while(gets(array)!=NULL)
  {
     int number[256]={0};
     int length;
     int i,j;
 
     if(first)
       printf("\n");
      first =1;
     length =strlen(array);                
    
     for(i =0;i<length;i++)
     {
       number[array[i]]++; 
     }
    
      for(i=1;i<=length;i++)
      {            
       for(j=255;j>0;j--)
       {         
         if(number[j]==i)
         {
           printf("%d %d\n",j,i);
         }
       }

     }    
  }
system("pause");
//return 0;
}

acm 10038 Jolly Jumpers

 [心得] : 0.008
測試資料5 -3 1 -2 0 1

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

int main()
{
    int a;
    while(scanf("%d",&a)==1)
    {
       int i;
       int flag =1;
       int array[4000]={0};
       int map[4000]={0};
       int differ;

      for(i =1;i<=a;i++)
        scanf("%d",&array[i]);
              
      for(i=1;i<a;i++)
      {    
           differ = abs(array[i+1]-array[i]);  
             
        if(differ >=a ||differ<1 || map[differ])
        {  
            flag=0;
            printf("Not jolly\n");
            break;
        }
        else
         map[differ] =1;
  
      }
        if(flag)
           printf("Jolly\n");
    }                
 

    return 0;
}

2012年1月2日 星期一

C about -- memset(matrix, 0, sizeof(matrix))

可以用於陣列初始化:
例如: 宣告三個陣列
#define MAXSIZE 8

int map[MAXSIZE+1];
int left[2*MAXSIZE+1];
int right[2*MAXSIZE+1];

 方法一
    memset(map,  0, sizeof(map));
    memset(left, 0, sizeof(left));
    memset(right,0, sizeof(right));

 方法二     
    memset(map,  0, sizeof(int)*(MAXSIZE+1));
    memset(left, 0, sizeof(int)*(2*MAXSIZE+1));
    memset(right,0, sizeof(int)*(2*MAXSIZE+1));

需要注意的是 ,不可以使用memset初始化為1

memset(matrix, 1, sizeof(matrix)); //會失敗
memset(matrix, -1, sizeof(matrix)); //OK
memset(matrix, 0, sizeof(matrix));//OK

memset為字元填入的函式,整數由2或4個位元組(字元)組成
設定的值是0x01,但存入的值卻是0x0101,而導致錯誤的答案
而-1則是0xFF,存入的值是0xFFFF,不會影響答案

#include <stdio.h>

int matrix[5][5];

void init_matrix()
{
  //設定陣列內的值全為-1
  memset(matrix, 1, sizeof(matrix));
}
int main()
{
    int i,j;
    init_matrix();
    for(i=0;i< 5;i++){
       for(j=0;i< 5;i++)
         printf("matrix[%d][%d] =%d\n",i,j,matrix[i][j]);  
    }
    system("pause");