注册 登录
编程论坛 C++教室

挑战TJU1031

leeco 发布于 2007-07-11 01:29, 1259 次点击

http://acm.tju.edu.cn/toj/showp1031.html
比代码短,我的代码是1.0K,自认为非常精短
--------------------------------------------------------------------------------
Judge Status Prob. Lang. Code Time Memory User
Accepted 1031 C++ 1.0K 0:00.00 672K lecoo

17 回复
#2
stupid_boy2007-07-11 10:46

用了672K的内存.....

鄙人用两种方法做了..一种用了16K内存,一种用了144K内存 也都是0MS

非常有兴趣拜读楼主大人的1K代码..请楼主发给我观摩一下.

感激不尽...

#3
leeco2007-07-11 15:34
回复:(stupid_boy)用了672K的内存.....鄙人用两种方...

你用了16K内存?不敢相信啊,贴上来看看
[UserName=stupid_boy]

程序代码:

#include <stdio.h>


#define PC(x) putchar(x)
#define PCD(x,y) putchar(digits[ch-'0'][x]?y:' ')


int digits[10][7]={1,0,1,1,1,1,1,0,0,0,0,1,0,1,1,1,1,0,1,1,0,1,1,1,0,1,0,1,0,1,0,1,
    1,0,1,1,1,1,1,0,0,1,1,1,1,1,0,1,1,1,0,0,0,1,0,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,};


void out(int s,char ch,int k)
{
    switch(k){
    case 0:
    case 2:
    case 4:
        PC(' ');
        for(int i=0;i<s;i++){
            PCD(k/2,'-');
        }
        PC(' ');
        break;
    case 1:
    case 3:
        PCD(k+2,'|');
        for(int i=0;i<s;i++){
            PC(' ');
        }
        PCD(k+3,'|');
        break;
    }
}


void out(int s,char* str,int suit)
{
    out(s,*str,suit);
    for(char *p=str+1;*p;p++){
        PC(' ');
        out(s,*p,suit);
    }
}


int main()
{
    char buf[100];
    int s;
    while(scanf(\"%d %s\",&s,buf)!=EOF && s){
        out(s,buf,0);
        PC('\n');
        for(int i=0;i<s;i++){
            out(s,buf,1);
            PC('\n');
        }
        out(s,buf,2);
        PC('\n');
        for(int i=0;i<s;i++){
            out(s,buf,3);
            PC('\n');
        }
        out(s,buf,4);
        PC('\n');
        PC('\n');
    }
}


[/UserName]

#4
stupid_boy2007-07-11 15:45
回复:(leeco)挑战TJU1031
PKU上面memory是16k,这个是比较好的方法

[UserName=leeco]

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

int code[5][30]=
{
{0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0},
{1,0,1,0,0,1,0,0,1,0,0,1,1,0,1,1,0,0,1,0,0,0,0,1,1,0,1,1,0,1},
{0,0,0,0,0,0,0,1,0,0,1,0,0,1,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0},
{1,0,1,0,0,1,1,0,0,0,0,1,0,0,1,0,0,1,1,0,1,0,0,1,1,0,1,0,0,1},
{0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,0,0,1,0}
};

int main()
{
int i,j,m,n,k,k1,posS;
char s[9];
while(1){
scanf("%d",&n);
scanf("%s",&s);
if(n==0&&strcmp(s,"0")==0)break;

for(i=0; i<5; i++)
{
if(!(i%2))
{
for(posS=0; s[posS]!='\0'; posS++)
{
for(m=0,j=(int)(s[posS]-'0')*3; m<3; m++,j++)
{
if((j%3==0||(j+1)%3==0)&&(i%2==0))
printf(" ");
else
{
for(k=0; k<n; k++)
{
if(code[i][j]) printf("-");
else printf(" ");
}
}
}
printf(" ");
}
printf("\n");
}
else
{
for(k=0; k<n; k++)
{
for(posS=0; s[posS]!='\0'; posS++)
{
for(m=0,j=(int)(s[posS]-'0')*3; m<3; m++,j++)
{
if(j%3==0||(j+1)%3==0)
{
if(code[i][j]) printf("|");
else printf(" ");
}
else
for(k1=0; k1<n; k1++)
printf(" ");
}
printf(" ");
}
printf("\n");
}
}
}
printf("\n");
}

return 0;
}

[/UserName]
#5
stupid_boy2007-07-11 15:50
回复:(leeco)挑战TJU1031
[UserName=leeco]144k那个是最笨的方法, 用数组做的..一点技术都没有,纯粹的体力劳动

我就不发那个了.

随便问一下.你是哪个大学的?大几了?

我写的代码很长.今天看了你的代码,有收获!![/UserName]
#6
stupid_boy2007-07-11 15:59

leeco你的代码我复制到VC里面运行不了.....

#7
leeco2007-07-11 16:02

你是在存的时候就分成了"顶行","上段","中行","下段","底行"这五个部分?

#8
leeco2007-07-11 16:04
回复:(stupid_boy)leeco你的代码我复制到VC里面运行...
你在C++的编译器上编译吧,可能是我for(int...)这样的语法写习惯了,我一直是用C++的
哦对还重载了一个out函数

[此贴子已经被作者于2007-7-11 16:05:58编辑过]

#9
stupid_boy2007-07-11 16:09
以下是引用leeco在2007-7-11 16:02:56的发言:

你是在存的时候就分成了"顶行","上段","中行","下段","底行"这五个部分?

饿.
code数组里面就是这样了
饿.

#10
leeco2007-07-11 16:30
回复:(stupid_boy)回复:(leeco)挑战TJU1031
上海师范大学,将要大三了
#11
HJin2007-07-11 18:49
回复:(stupid_boy)以下是引用leeco在2007-7-11 16:...
very good. will do it later myself.

#12
野比2007-07-11 20:02

No time to do this myself...

btw. why not show us your codes?

#13
leeco2007-07-11 20:47
回复:(野比)No time to do this myself...btw. why...
把我的show了想挑战的人还怎么挑战啊,思路都按照我的走了,只要把我的改一下就更短了,事实上我已经改到660字节了,基本没有任何可读性……
#14
stupid_boy2007-07-11 21:18

照你这样发展下去。。。内存市场和硬盘市场都要重新洗牌了。。。

偶觉得写程序现在不必过分的简短导致失去可读性

偶觉得写别人看得懂的程序才是正道

谭浩强也是这样说的嘛

[此贴子已经被作者于2007-7-11 21:32:19编辑过]

#15
leeco2007-07-11 22:26
回复:(stupid_boy)照你这样发展下去。。。内存市场...
程序员的创造力和代码的可维护性成反比。
是我在《高效程序设计的奥秘》里看到类似的话。

在毕业之前我还是坚持注重创造力和程序的高效。
#16
HJin2007-07-11 23:11
回复:(leeco)挑战TJU1031

/*---------------------------------------------------------------------------
File name: TJU1031.cpp
Author: HJin (email: fish_sea_bird [at] yahoo [dot] com )
Created on: 7/10/2007 21:53:53
Environment: Windows XP Professional SP2 English +
Visual Studio 2005 v8.0.50727.762


Modification history:
===========================================================================
7/11/2007 12:20:44
-----------------------------------------------------------
corrected a bug for drawing the digit 3. leeco pointed out this bug. Thanks
go to him.


Problem statement: (http://acm.tju.edu.cn/toj/showp1031.html)
---------------------------------------------------------------------------

1031. LC-Display
--------------------------------------------------------------------------------
Time Limit: 1.0 Seconds Memory Limit: 65536K
Total Runs: 649 Accepted Runs: 210

--------------------------------------------------------------------------------


A friend of you has just bought a new computer. Until now, the most powerful
computer he ever used has been a pocket calculator. Now, looking at his new
computer, he is a bit disappointed, because he liked the LC-display of his
calculator so much. So you decide to write a program that displays numbers in
an LC-display-like style on his computer.

Input

The input contains several lines, one for each number to be displayed. Each
line contains two integers s, n (1 ≤ s ≤ 10, 0 ≤ n ≤ 99,999,999), where n is
the number to be displayed and s is the size in which it shall be displayed.

The input file will be terminated by a line containing two zeros. This line
should not be processed.


Output

Output the numbers given in the input file in an LC-display-style using s "-"
signs for the horizontal segments and s "|" signs for the vertical ones. Each
digit occupies exactly s+2 columns and 2s+3 rows. (Be sure to fill all the
white space occupied by the digits with blanks, also for the last digit.) There
has to be exactly one column of blanks between two digits.

Output a blank line after each number. (You will find a sample of each digit in
the sample output.)


Sample Input (also the content of my input file TJU1031_Input.txt)
-------------------------------------------------------------------
2 12345
3 67890
4 1234567890
0 0


Sample Output

-- -- --
| | | | | |
| | | | | |
-- -- -- --
| | | | |
| | | | |
-- -- --

--- --- --- --- ---
| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- ---
| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- --- ---

Analysis:
---------------------------------------------------------------------------
(no analysis is needed.)


Sample output:
---------------------------------------------------------------------------
-- -- --
| | | | | |
| | | | | |
-- -- -- --
| | | | | |
| | | | | |
-- -- --

--- --- --- --- ---
| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- ---
| | | | | | | |
| | | | | | | |
| | | | | | | |
--- --- --- ---

---- ---- ---- ---- ---- ---- ---- ----
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
---- ---- ---- ---- ---- ---- ----
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
| | | | | | | | | | | | | |
---- ---- ---- ---- ---- ---- ----

Press any key to continue . . .


Reference:
---------------------------------------------------------------------------
1. http://acm.tju.edu.cn/toj/showp1031.html

*/

#include <iostream>
#include <fstream>
using namespace std;

class Lcd
{
friend std::ostream& operator<<(std::ostream& os, const Lcd& obj);
public:
Lcd(int s_, int n_) : s(s_), n(n_)
{
int i;
int j;
int numRows = 2*s+3;
int numCols = getNumberOfDigits(n)*(s+3);
int q = n;
int r = q % 10;
int counter = 0;

// allocate memory
a = new char*[numRows];
for(i=0; i<numRows; ++i)
{
a[i] = new char[numCols];
}

// initialize the 2d buffer
for(i=0; i<numRows; ++i)
{
for(j=0; j<numCols-1; ++j)
{
a[i][j] = ' ';
}
a[i][j] = '\n';
}

// draw the digits one by one, from last digit to first digit
// (from right to left).
while(q>0)
{
lastCol = numCols - counter*(s+3) - 2;
drawDigit(r);

++counter;
q /= 10;
r = q % 10;
}
}

~Lcd()
{
// deallocate memory
for(int i=0; i<2*s+3; ++i)
{
delete [] a[i];
}
delete [] a;
}

private:
/**
calculate number of digits of a number.
*/
int getNumberOfDigits(int n) const
{
int c = 0; // counter for # of digits

do
{
++c;
n /= 10;
}
while(n>0);

return c;
}

/** Draw a stroke.
@param m index of strokes.
m = 0 --- top horizontal stroke
m = 1 --- left top vertical stroke
m = 2 --- right top vertical stroke
m = 3 --- middle horizontal stroke
m = 4 --- left bottom vertical stroke
m = 5 --- right bottom vertical stroke
m = 6 --- bottom horizontal stroke
*/
void drawStroke(int m)
{
int i;
int j;
int row; // row position
int col; // column position

switch(m)
{
case 0:
case 3:
case 6:
row = m/3*(s+1);

for(j=1; j<=s; ++j)
{
a[row][lastCol-j] = '-';
}

break;
case 1:
case 2:
case 4:
case 5:
row = (m<3 ? 0 : 1)*(s+1)+1;
col = (m % 3 == 1 ? lastCol - s - 1 : lastCol);
for(i=row; i<=row+s-1; ++i)
{
a[i][col] = '|';
}
break;
}
}

/**
Draw a digit r: r =0..9.
*/
void drawDigit(int r)
{
switch(r)
{
case 0:
case 8:
drawStroke(0);
drawStroke(1);
drawStroke(2);
drawStroke(4);
drawStroke(5);
drawStroke(6);
if(r==8)
{
drawStroke(3);
}
break;

case 1:
case 7:
drawStroke(2);
drawStroke(5);

if(r==7)
{
drawStroke(0);
}
break;

case 2:
case 3:
drawStroke(0);
drawStroke(2);
drawStroke(3);
//drawStroke(4); // Bug
drawStroke(6);
if(r==2)
{
drawStroke(4);
}
if(r==3)
{
drawStroke(5);
}

break;

case 4:
case 9:
drawStroke(1);
drawStroke(2);
drawStroke(3);
drawStroke(5);

if(r==9)
{
drawStroke(0);
drawStroke(6);
}

break;

case 5:
case 6:
drawStroke(0);
drawStroke(1);
drawStroke(3);
drawStroke(5);
drawStroke(6);
if(r==6)
{
drawStroke(4);
}

break;
}
}

private:
// disable copy ctor and assignment operator
Lcd(const Lcd&);
Lcd& operator= (const Lcd&);

private:
int s;
int n;
char **a; // 2d buffer

/**
last column for a digit.
*/
int lastCol;
};

std::ostream& operator<<(std::ostream& os, const Lcd& obj)
{
int numRows = 2*obj.s+3;
int numCols = obj.getNumberOfDigits(obj.n)*(obj.s+3);
for(int i=0; i< numRows; ++i)
{
for(int j=0; j< numCols; ++j)
{
os<<obj.a[i][j];
}
}

return os;
}


int main()
{
int s;
int n;

ifstream ifs("TJU1031_Input.txt");
ofstream ofs("TJU1031_Output.txt");

if(!ifs)
{
cout<<"cannot open input file.\n";
exit(0);

}
if(!ofs)
{
cout<<"cannot open output file.\n";
exit(0);
}

while(1)
{
ifs>>s;
ifs>>n;
if( (s==0 && n==0) || s<1 || s> 10 ) // || n<0 || n>99999999 )
break;

Lcd* obj = new Lcd(s, n);

ofs<<*obj<<endl;
cout<<*obj<<endl;

delete obj;
}

ifs.close();
ofs.close();

return 0;
}

[此贴子已经被作者于2007-7-12 3:26:45编辑过]

#17
leeco2007-07-12 02:26
看了一下,您似乎多写了一句drawStroke(4);导致3的输出有问题。
#18
HJin2007-07-12 03:27
thanks, the mistake is corrected now.
1