以前在OJ上做的一些题目,总结了一下,写成结题报告,既是给自己的一个总结,也为其他想要参考的ACMer提供一个方便。
POJ 1503 Integer Inquiry
用字符串模拟数字相加的题目,题目本身并没有什么难度,但要求有足够的细心,然后就是满10进位的操作。
Code
<!---->#include < iostream >
#include < string >
using namespace std;
int main()
{
char add[ 105 ];
char sum[ 105 ] = { 0 };
int i,j,tag;
while (gets(add))
{
if (strcmp(add, " 0 " ) == 0 )
break ;
i = 104 , j = strlen(add) - 1 , tag = 0 ;
while (j >= 0 )
{
if (sum[i] + add[j] + tag - ' 0 ' >= 10 )
{
sum[i] = ((sum[i] + add[j] + tag - ' 0 ' ) % 10 );
tag = 1 ;
i -- ;
j -- ;
}
else
{
sum[i] += (add[j] + tag - ' 0 ' );
tag = 0 ;
i -- ;
j -- ;
}
}
while (i >= 0 )
{
if (sum[i] + tag >= 10 )
{
sum[i] = (sum[i] + tag) % 10 ;
tag = 1 ;
i -- ;
}
else
{
sum[i] += (tag);
tag = 0 ;
i -- ;
}
}
}
i = 0 ;
while (sum[i] == 0 )
i ++ ;
if (i == 105 )
cout << " 0 " ;
while (i <= 104 )
{
printf( " %d " ,sum[i]);
i ++ ;
}
cout << endl;
return 0 ;
}
POJ 1504 Adding Reversed Numbers
一道对数字进行操作的题目,大概的意思就是:给定两个数字,先将这两个数字分别进行转置,然后再计算转置之后两数的和,最后再将这个结果转置。这个地方所指的转置就是把数中的数字字符全部倒一下次序,最高位变成最低位,最低位变成最高位。 当然,也可以用整数类型来存储两个数,不过个人觉得用数组进行存储时操作会简单一点。 程序中大致有以下几个功能模块,一个用来将字符串中的元素倒置,另一个用来求两个字符串的和。
Code
<!---->#include < iostream >
#include < string >
using namespace std;
char * getReversed( char value[])
{ // 将字符串value中的元素倒置
int length = strlen(value);
char * temp = new char [length + 1 ];
int i = 0 ;
while (i < length)
{
temp[i] = value[length - i - 1 ];
i ++ ;
}
temp[i] = ' \0 ' ;
return temp;
}
void getCharSum( char * first, char * second)
{ // 求字符串型first和second的和,并将结果逆置输出
int flength = strlen(first);
int slength = strlen(second);
int sumlength = (flength > slength ? flength:slength) + 1 ;
char * sum = new char [sumlength];
sum[ 0 ] = ' 0 ' ;
int tag = 0 ,i = 1 ;
while (i <= flength && i <= slength)
{
sum[sumlength - i] = (first[flength - i] + second[slength - i] + tag - 2 * ' 0 ' ) % 10 + ' 0 ' ;
if (first[flength - i] + second[slength - i] + tag - 2 * ' 0 ' >= 10 )
tag = 1 ;
else
tag = 0 ;
i ++ ;
}
while (i <= flength)
{
sum[sumlength - i] = (first[flength - i] + tag - ' 0 ' ) % 10 + ' 0 ' ;
if (first[flength - i] + tag - ' 0 ' >= 10 )
tag = 1 ;
else
tag = 0 ;
i ++ ;
}
while (i <= slength)
{
sum[sumlength - i] = (second[slength - i] + tag - ' 0 ' ) % 10 + ' 0 ' ;
if (second[slength - i] + tag - ' 0 ' >= 10 )
tag = 1 ;
else
tag = 0 ;
i ++ ;
}
sum[ 0 ] = tag + ' 0 ' ;
int top = 0 ;
for ( int j = sumlength - 1 ; j >= 1 ; j -- )
if (sum[j] != ' 0 ' )
{
top = j;
break ;
}
for ( int j = top; j >= 1 ; j -- )
cout << ( char )sum[j];
if (sum[ 0 ] != ' 0 ' )
cout << ( char )sum[ 0 ];
cout << endl;
}
int main()
{
int n;
cin >> n;
while (n -- )
{
char * first = new char [ 11 ], * second = new char [ 11 ];
cin >> first >> second;
first = getReversed(first);
second = getReversed(second);
getCharSum(first,second);
}
return 0 ;
}
POJ 1517 u Calculate e
Code
<!---->#include < iostream >
using namespace std;
int main( void )
{
double e = 2.5 ;
int i = 3 ,n = 9 ,s = 2 ;
printf( " n e\n- -----------\n0 1\n " );
printf( " 1 2\n2 2.5\n " );
while (i <= n)
{
s = s * i;
e += 1.0 / s;
printf( " %d %.9f\n " ,i ++ ,e);
}
return 0 ;
}
POJ 1519 Digital Roots
题目的意思就是对一个给定的正整数,不断的将它的各位上数字加起来,直到最后的结果为一个1位数。
看 完题目,觉得用关门递归来做会轻松很多。不过,我个人觉得如果一开始就用一个字符串来存储输入的整数,后面对其操作就会简单一点,如果用整形存储,后面会 不好操作。最后,也是最容易忽略的一点就是,题目并没有明确说明输入的整数的范围,所以,不适合用整形或长整形来存储输入的数字,而更适宜采用数组的形式。
Code
<!---->#include < stdio.h >
#include < string .h >
#define MAX 2000
int d( int * a)
{ // 计算字符串a各位上数字的总和
int i, sum = 0 ;
for (i = 1 ; i <= a[ 0 ]; i ++ )
{
sum += a[i];
}
return sum;
}
int dint( int a)
{
int sum = 0 ;
while (a)
{
sum += a % 10 ;
a /= 10 ;
}
return sum;
}
int main()
{
char s[MAX];
int a[MAX], i, k;
while (scanf( " %s " , s))
{
if (s[ 0 ] == ' 0 ' )
break ;
a[ 0 ] = strlen(s);
for (i = 1 ; i <= a[ 0 ]; i ++ )
{
a[i] = s[i - 1 ] - ' 0 ' ;
}
k = d(a);
while (k / 10 != 0 )
k = dint(k);
printf( " %d\n " , k);
}
return 0 ;
}
POJ 1528 Perfection
对于给定的整数,判断它所属的类型。题目定义的Perfection是这样一种整数:它所有的因子之和刚好等于它本身,如果因子之和较本身小或大则属于其他的类型。 从1开始一起到n/2,判断是否为该数的因子,如果是,则加起来,最后判断即可。
Code
<!---->#include < stdio.h >
#include < math.h >
int main( void )
{
int n,s,i;
printf( " PERFECTION OUTPUT\n " );
while (scanf( " %d " , & n) != EOF)
{
if (n == 0 ) break ;
s = 0 ;
for (i = 1 ;i <= n / 2 ;i ++ )
if (n % i == 0 )
s += i;
if (s == n) printf( " %5d PERFECT\n " ,n);
else if (s < n) printf( " %5d DEFICIENT\n " ,n);
else printf( " %5d ABUNDANT\n " ,n);
}
printf( " END OF OUTPUT\n " );
return 0 ;
}
POJ 1543 Perfect Cubes
考虑到题目中给出的数据并不大,所以就直接采用了暴力破解的办法。
Code
<!---->#include < iostream >
using namespace std;
int main()
{
int n;
cin >> n;
for ( int i = 6 ; i <= n; i ++ )
{
int cube = i;
for ( int i = 2 ; i < n; i ++ )
for ( int j = i; j < n; j ++ )
for ( int k = j; k < n; k ++ )
if ((cube * cube * cube) == i * i * i + j * j * j + k * k * k)
{
printf( " Cube = %d, Triple = (%d,%d,%d)\n " ,cube,i,j,k);
break ;
}
}
return 0 ;
}
POJ 1547 Clay Bully
对于输入的n组数据,输入一组,就把该组数据的体积计算出来,n组数据输入完毕之后,就会得到n个体积,因为题目中规定了只有一个bully和一个victim,那么,n个数据中会有一个最小,一个最大,找到这两个数据即可得到结果。
Code
<!---->#include < iostream >
using namespace std;
int main()
{
int n;
int x,y,z;
while (cin >> n)
{
if (n == - 1 )
break ;
int * cube = new int [n];
char student[ 9 ][ 10 ];
for ( int i = 0 ; i < n; i ++ )
{
cin >> x >> y >> z;
cube[i] = x * y * z;
cin >> student[i];
}
int max = 0 , min = 65325 ;
int bully, victim;
for ( int i = 0 ; i < n; i ++ )
{
if (cube[i] < min)
{
min = cube[i];
victim = i;
}
if (cube[i] > max)
{
max = cube[i];
bully = i;
}
}
cout << student[bully] << " took clay from " << student[victim] << " . " << endl;
}
return 0 ;
}
POJ 1552 Doubles
计算给定的数字序列中一个数为另一个的2倍的情况的次数。由于每组数据的数据量都比较小,故直接用两个for循环即能实现。
Code
<!---->#include < iostream >
using namespace std;
int main()
{
int list[ 16 ];
while (cin >> list[ 0 ])
{
if (list[ 0 ] == - 1 )
break ;
int number = 1 ;
while ( 1 )
{
cin >> list[number];
if (list[number] == <span
分享到:
评论