2015年7月27日 星期一

[C][瘋狂程設][CPE考題20140325] 14A3.UVA10018:Reverse and Add

Reverse and Add

The "reverse and add" method is simple: choose a number, reverse its digits and add it to the original. If the sum is not a palindrome (which means, it is not the same number from left to right and right to left), repeat this procedure. 
For example: 
195 Initial number 
591 
----- 
786 
687 
----- 
1473 
3741 
----- 
5214 
4125 
----- 
9339 Resulting palindrome 

In this particular case the palindrome 9339 appeared after the 4th addition. This method leads to palindromes in a few step for almost all of the integers. But there are interesting exceptions. 196 is the first number for which no palindrome has been found. It is not proven though, that there is no such a palindrome. 

Task : 
You must write a program that give the resulting palindrome and the number of iterations (additions) to compute the palindrome. 

You might assume that all tests data on this problem: 
- will have an answer , 
- will be computable with less than 1000 iterations (additions), 
- will yield a palindrome that is not greater than 4,294,967,295. 

Input

The first line will have a number N with the number of test cases, the next N lines will have a number P to compute its palindrome.
3
195
265
750

Output

For each of the N tests you will have to write a line with the following data : minimum number of iterations (additions) to get to the palindrome and the resulting palindrome itself separated by one space.
4 9339 
5 45254 
3 6666 

Notes:


1.反轉輸入的數字

void reverse_data(int *num,int size,char rev_data[]){

 int m=*num;
 char data[size];
 
 /*------reverse------*/
 sprintf(data,"%d",m);
 strcpy(rev_data,data);
 strrev(rev_data);
 //printf("[%d]%d,%s,%s\n",__LINE__,size,data,rev_data);
}

Code:


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

void reverse_data(int *num,int size,char rev_data[]){

 int m=*num;
 char data[size];
 
 /*------reverse------*/
 sprintf(data,"%d",m);
 strcpy(rev_data,data);
 strrev(rev_data);
 //printf("[%d]%d,%s,%s\n",__LINE__,size,data,rev_data);
}

int rev_and_add(int *num){

 int m=*num;
 int palindrome;
 int length=sizeof(m);
 char rev_num[length];
 
 /*------reverse------*/
 reverse_data(&m,length,rev_num);
 
 /*------add------*/
 m+=atoi(rev_num);
 length=sizeof(m);
 reverse_data(&m,length,rev_num);
 
 /*-----test palindrome, 0 means yes, 1 means no.-----*/
 char sum[length];
 sprintf(sum,"%d",m);
 //printf("[%d]%s,%s\n",__LINE__,sum,rev_num);
 
 (strcmp(sum,rev_num)==0)?palindrome=0:palindrome=1;
 //printf("[%d],p=%d\n",__LINE__,palindrome);
 *num=m;
 return palindrome;
 
 //return 0;
}

int main(void){

 int total,count,i=0,input,act;
 
 scanf("%d",&total);
 
 while(i<total){
  count=0;
  i++;
  scanf("%d",&input);
  
  do{
   //printf("[%d]count=%d\n",__LINE__,count);
   act=rev_and_add(&input);
   count++;
  }while(act==1);
   
  printf("%d %d\n",count,input);
 }

 return 0;
}

[C][瘋狂程設][CPE考題20140527] 14C2.UVA10190 : Divide, But Not Quite Conquer! :

Problem C: Divide, But Not Quite Conquer!

Your goal in this problem is to divide a certain integer n by another integer m until n = 1, obtaining a sequence of numbers. Lets call a[i] each number of this sequence, and let's say it has k numbers (i.e. you must do k-1 succesive divisions to reach n = 1). You can only have this sequence if the following restrictions are met:
a[1] = n, a[i] = a[i-1] div m, for all 1 < i <= k 
a[i] is divisible by m (that is, a[i] mod m = 0) for all 1 <= i < k 
a[1] > a[2] > a[3] ... > a[k] 
For instance, if n = 125 and m = 5, you have 125, 25, 5 and 1 (you did 3 divisions: 125/5, 25/5 and 5/5). So, k = 4, a[1] = 125, a[2] = 25, a[3] = 5 and a[4] = 1. If n = 30 and m = 3, you have 30, 10, 3 and 1. But a[2] = 10, and 10 mod 3 = 1, so there is no sequence because it violates restriction 2. When the sequence doesn't exist we think it's not fun and, thus, very boring!

input

The input will consist on an arbitrary number of lines. Each line will consist of two non-negative integers n,m which are both less than 2000000000. You must read until you reach the end of file.
125 5
30 3
80 2
81 3

output

For each pair n,m you must print the correpondent sequence a (as defined above) in a single line, with each adjacent numbers of the sequence separated by a single space. In the case the sequence doesn't exist because it violates some restriction, just print the phrase "Boring!" in a single line (without the quotes).
125 25 5 1
Boring!
Boring!
81 27 9 3 1

notes:


1.利用題目給定輸入的最大值"2000000000",設定array的大小


The input will consist on an arbitrary number of lines. 
Each line will consist of two non-negative integers n,m which are both less than 2000000000.

#define MAX 2000000000>>20


2.計算divide的答案。必須要排除除數為0的狀態,所以加上一個bool值"pass",協助判斷是否具有商數array

 while(scanf("%ld %ld",÷nd,&divisor)!=EOF){
   
  int number[MAX],i=1,pass=0;
  number[i]=dividend;
  
  //calculate the array
  while(number[i]>1&&divisor>1){
   i++;
   pass=1;
   number[i]=number[i-1]/divisor;
   if((number[i-1]%divisor)!=0){
    pass=0;
    break;
   }
  }
                .
                .
                . 
        }
  

Code:


#include <stdio.h>

#define MAX 2000000000>>20

int main(void){

 long int dividend,divisor;
 
 while(scanf("%ld %ld",÷nd,&divisor)!=EOF){
   
  int number[MAX],i=1,pass=0;
  number[i]=dividend;
  
  //calculate the array
  while(number[i]>1&&divisor>1){
   i++;
   pass=1;
   number[i]=number[i-1]/divisor;
   if((number[i-1]%divisor)!=0){
    pass=0;
    break;
   }
  }
  
  //show the result
  if(pass==1)
   for(int j=1;j≤i;j++)
    (number[j]==1)?printf("%d\n",number[j]):printf("%d ",number[j]);
  else
   printf("Boring!\n");
  
 }
 return 0;
}

[C][瘋狂程設][CPE考題20140923] 14E3.UVA12602:Nice Licence Plates

Nice Licence Plates

Alberta licence plates currently have a format of ABC-0123 (three letters followed by four digits).
We say that the licence plate is "nice" if the absolute difference between the value of the first part and the value of the second part is at most 100.
The value of the first part is calculated as the value of base-26 number (where digits are in [A..Z]). For instance, if the first part is "ABC", its value is 28 (0*26^2 + 1*26^1 + 2*26^0). So, the plate "ABC-0123" is nice, because |28-123|<=100.
Given the list of licence plate numbers, your program should determine if the plate is nice or not.

input

First line of the input contains an integer N (1<=N<=100), the number of licence plate numbers. Then follow N lines, each containing a licence plate in the format LLL-DDDD.
2
ABC-0123
AAA-9999

output

For each licence plate print on a line "nice" or "not nice" (without quotes) depending on the plate number being nice as described in the probem statement.
nice
not nice

Notes:


1.利用sscanf()分離出前三個字母與後四個數字

  scanf("%s",input);
  sscanf(input,"%[^-]-%d",letter,&digits);

2.計算前三個字母轉化成26進位當中所表示的數字大小

letter[0]-'A')*BASE*BASE+(letter[1]-'A')*BASE+(letter[2]-'A'

3.計算整數的絕對值: abs()

abs((letter[0]-'A')*BASE*BASE+(letter[1]-'A')*BASE+(letter[2]-'A')-digits);

Code:

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

#define BASE 26 
#define MAX 100


int main(void){

 int num,i=0,digits,result;;
 char *input,letter[3];

 scanf("%d",&num);
 
 while(i<num){
  scanf("%s",input);
  sscanf(input,"%[^-]-%d",letter,&digits);
  result = abs((letter[0]-'A')*BASE*BASE+(letter[1]-'A')*BASE+(letter[2]-'A')-digits);
  printf("%s\n",abs(result)<=MAX?"nice":"not nice");
  i++;
 }
 return 0;
}

[C][瘋狂程設][03_運算子] A042_轉轉算2的冪次方、A043_十六進位檢視器

A042:轉轉算2的冪次方


輸入一個整數 n (0≤n<31),輸出2^n。
input:10
output:1024

Notes:

1.計算2的冪次方

使用 Arithmetic shift算術位移的left shift'<<'
int num=1;
num<<1: 數字1,左位移1位,表示1*2=2
num<<2: 數字1,左位移2位,表示1*2*2=4

Code:

#include <stdio.h>

int main(void){
 int input;
 scanf("%d",&input);
 printf("%d",1<<input);
 return 0;
}



A043:十六進位檢視器


輸入一段連文字,印出該連文字的十六進位資料
input: talks
output:74 61 6C 6B 73

Notes:


1.getchar

getchar會讀取每個字元,包含空白、跳格、換行字元。
scanf()只會讀取數字,並且會略過空白、跳格、換行字元。
本題若要使用scanf,擇要改寫成下列格式,才能抓到每個字元,若將%c改成%s,則只會抓到第一個字元:
        while((scanf("%c",&input)!=EOF){
  if(input!=' ')
   printf("%X ",input);
 }

2.十六進位顯示方式

使用"%x"或者"%X"皆可,差別在於結果顯示的字母是小寫或大寫,舉例如下:
    printf("%x ",input); //74 61 6c 6b 73
    printf("%X ",input); //74 61 6C 6B 73

3.去除空白字元

因為是輸入的方式,採取逐字元抓取,所以空白字元也會被抓進來處理。
但是題目的輸出不要顯示空白位元,所以要加入條件,遇到空白字元的時候不列印。
    if(input!=' ')


Code:

#include <stdio.h>

int main(void){

 int input;
 
 while((input=getchar())!=EOF){
  if(input!=' ')
   printf("%X ",input);
 }

 return 0;
}