2009年2月7日 星期六

Q446: Kibbles `n' Bits `n' Bits `n' Bits

// Run time: 0.000
#include <stdio.h>
void print(int num);

int main()
{
int n;
int a, b;
char op;

scanf("%d", &n);
while (n--)
{
scanf("%X %c %X", &a, &op, &b);
print(a);
printf(" %c ", op);
print(b);
printf(" = ");
if (op == '+')
printf("%d\n", a+b);
else
printf("%d\n", a-b);

}
}

void print(int num)
{
char arr[15];
int mod;
int i;

for ( i = 0; i < 13; i++)
arr[i] = '0';

i = 0;
if (!num)
{
printf("%013d", num);
return;
}

while (num)
{
mod = num % 16;
switch (mod)
{
case 0: arr[i] = arr[i+1] = arr[i+2] = arr[i+3] = '0';
break;
case 1: arr[i+3] = arr[i+2] = arr[i+1] = '0', arr[i] = '1';
break;
case 2: arr[i+3] = arr[i+2] = arr[i] = '0', arr[i+1] = '1';
break;
case 3: arr[i+3] = arr[i+2] = '0', arr[i+1] = arr[i] = '1';
break;
case 4: arr[i+3] = arr[i+1] = arr[i] = '0', arr[i+2] = '1';
break;
case 5: arr[i+3] = arr[i+1] = '0', arr[i+2] = arr[i] = '1';
break;
case 6: arr[i+3] = arr[i] = '0', arr[i+2] = arr[i+1] = '1';
break;
case 7: arr[i+3] = '0', arr[i+2] = arr[i+1] = arr[i] = '1';
break;
case 8: arr[i+3] = '1', arr[i+2] = arr[i+1] = arr[i] = '0';
break;
case 9: arr[i+3] = arr[i] = '1', arr[i+2] = arr[i+1] = '0';
break;
case 10: arr[i+3] = arr[i+1] = '1', arr[i+2] = arr[i] = '0';
break;
case 11: arr[i+3] = arr[i+1] = arr[i] = '1', arr[i+2] = '0';
break;
case 12: arr[i+3] = arr[i+2] = '1', arr[i+1] = arr[i] = '0';
break;
case 13: arr[i+3] = arr[i+2] = arr[i] = '1', arr[i+1] = '0';
break;
case 14: arr[i+3] = arr[i+2] = arr[i+1] = '1', arr[i] = '0';
break;
case 15: arr[i+3] = arr[i+2] = arr[i+1] = arr[i] = '1';
break;
}
num /= 16;
i += 4;
}
for ( i = 12; i >= 0; i--)
printf("%c", arr[i]);
}

Q445: Marvelous Mazes

// Run time: 0.000
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int main()
{
char str[1000];
char ch;
int len;
int cnt;
int i;

while (gets(str) != NULL)
{
len = strlen(str);
cnt = 0; // 數字算 位數和 要用

// if enter only, and then a newline
if (!len)
{
putchar('\n');
continue;
}


for ( i = 0; i < len; i++)
{
if (isdigit(str[i]))
cnt += str[i] - 48; // 如果是數字就把每位數加起來
else
if (str[i] == '!') // 如果是 ! 就要換行
putchar('\n');

// 如果現在讀的是一個 A~Z or b(which is a blank)
else
{
if (str[i] == 'b') // if blank
ch = ' ';
else
ch = str[i];

while (cnt--)
printf("%c", ch);

cnt = 0;
}
}
putchar('\n');

}
}

Q455: Periodic Strings

// Run time: 0.010
#include <stdio.h>
#include <string.h>
void test(char str[81]);

int main()
{
char str[81];
int n;
scanf("%d", &n);
while (n--)
{
scanf("\n");
gets(str);
test(str);
if (n != 0)
printf("\n");
}

return 0;
}

void test(char str[81])
{
int i;
int len;
int length = strlen(str);
bool state = false;
for ( len = 1; len <= length; len++)
{
if (len == length)
{
printf("%d\n", len);
return;
}
if (!(length%len))
{
for ( i = 0; i+len < length; i++)
{
if (str[i] != str[i+len])
{
state = false;
break;
}
else
state = true;
}
}

if (state)
{
printf("%d\n", len);
return;
}
}

}

Q127: "Accordian" Patience

// Run time: 1.020
#include <stdio.h>
#define NUM 52
typedef struct {
char suit;
char rank;
} Card;
Card card[NUM];
int index[NUM]; // 指出每個陣列現在指到哪
int check[NUM][NUM];
void Accordian();

int main()
{
int i;
while (true)
{
scanf("%c", &card[0].rank);
if (card[0].rank == '#')
break;
else
{
scanf("%c ", &card[0].suit);
for ( i = 1; i < NUM-1; i++)
{
scanf("%c%c ", &card[i].rank, &card[i].suit);
}
scanf("%c%c", &card[NUM-1].rank, &card[NUM-1].suit);

for ( i = 0; i < NUM; i++)
check[i][0] = i;
for ( i = 0; i < NUM; i++)
index[i] = 1;
}

Accordian();
scanf("\n");
}
return 0;
}

void Accordian()
{
int max = NUM;
int i, j, k;
for (; ;)
{
int count = 0;
for ( i = 1; i < max; i++)
{
if ( i-3 >= 0 &&
(card[check[i][index[i]-1]].rank == card[check[i-3][index[i-3]-1]].rank ||
card[check[i][index[i]-1]].suit == card[check[i-3][index[i-3]-1]].suit))
{
check[i-3][index[i-3]] = check[i][index[i]-1]; // push in
index[i]--;
index[i-3]++;


if (!index[i]) // if it's empty after moving
{
for ( j = i; j < max-1; j++)
index[j] = index[j+1];
index[max-1] = 0;

for ( j = i; j < max-1; j++)
{
for ( k = 0; k < index[j]; k++)
check[j][k] = check[j+1][k];
}
max--;
}
i = 0;
count++;

}
else
if ( i-1 >= 0 &&
(card[check[i][index[i]-1]].rank == card[check[i-1][index[i-1]-1]].rank ||
card[check[i][index[i]-1]].suit == card[check[i-1][index[i-1]-1]].suit))
{
check[i-1][index[i-1]] = check[i][index[i]-1];
index[i]--;
index[i-1]++;


if (!index[i]) // if it's empty after moving
{
for ( j = i; j < max-1; j++)
index[j] = index[j+1];
index[max-1] = 0;

for ( j = i; j < max-1; j++)
{
for ( k = 0; k < index[j]; k++)
check[j][k] = check[j+1][k];
}
max--;
}
i = 0;
count++;
}

}
if (!count)
{
if (max == 1)
printf("1 pile remaining: 52");
else
{
printf("%d piles remaining:", max);
for ( i = 0; i < max; i++)
printf(" %d", index[i]);
}
printf("\n");
return;


}
}

}

Q412: Pi

/*
Run time: 0.310
判斷互質與否,可以直接用輾轉相除法找 gcd
如果 gcd is one 表示互質
這樣做會比用for loop 一個一個找有效率很多
*/
#include <stdio.h>
#include <math.h>
bool test(int a, int b);
void swap(int &a, int &b);
int gcd(int a, int b);
int total;

int main()
{
int n;
int i, j;
int count;
double PI;
while (scanf("%d", &n))
{
if (!n) break;

total = 0;
count = 0;
int *arr = new int[n];

for ( i = 0; i < n; i++)
scanf("%d", &arr[i]);

for ( i = 0; i < n; i++)
for ( j = i+1; j < n; j++)
if (test(arr[i], arr[j]))
count++;

if (!count) printf("No estimate for this data set.\n");
else
{
PI = sqrt(6.0*total/count);
printf("%.6lf\n", PI);
}

}

}

bool test(int a, int b)
{
total++;
int i;
if (a == b) return false;

if (a > b) swap(a, b);

if (gcd(a, b) == 1)
return true;
else
return false;
}

void swap(int &a, int &b)
{
int tmp;
tmp = a;
a = b;
b = tmp;
}

int gcd(int a, int b)
{
if (!a)
return b;
else
return gcd(b%a, a);

}