标签:
在使用 C# 语言解 ACM 题的时候,如果能够有一个 ReadInt32 方法直接从标准输入读取整数比较方便的。下面就是一个 I/O 助手类 IOHelper:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
|
namespace Skyiv { using System; using System.IO; using System.Text; sealed class IOHelper
: IDisposable { static readonly Encoding
Encoding = Encoding.ASCII; //
or UTF8 ? static readonly byte []
EOLS = Encoding.GetBytes(Environment.NewLine); static readonly byte []
BLANKS = { 9, 10, 13, 32 }; //
tab,lf,cr,space static readonly byte EOF
= 0; //
assume ‘\0‘ not in input file byte []
buf = new byte [32]; //
for Write(int n) byte []
buffer = new byte [64
* 1024]; int current
= 0; int count
= 0; BinaryReader
reader; BinaryWriter
writer; public IOHelper() : this (Console.OpenStandardInput(),
Console.OpenStandardOutput()) {} public IOHelper(Stream
reader, Stream writer) { this .reader
= new BinaryReader(reader); this .writer
= new BinaryWriter(writer); } byte ReadByte() { if (current
>= count) { count
= reader.Read(buffer, current = 0, buffer.Length); if (count
== 0) return EOF; } return buffer[current++]; } public static byte []
GetBytes( string str) { return Encoding.GetBytes(str); } public int ReadInt32() { var n
= 0; var ok
= false ; for ( byte b;
(b = ReadByte()) != EOF; ) { if (Array.IndexOf(BLANKS,
b) >= 0) if (ok) break ; else continue ; n
= n * 10 + (b - ‘0‘ ); ok
= true ; } return n; } public int ReadLine( byte []
buffer) { var n
= 0; while (n
< buffer.Length) { var b
= ReadByte(); if (b
== EOLS[0]) { if (EOLS.Length
== 2 && ReadByte() != EOLS[1]) throw new InvalidDataException( "Invalid
EOL" ); break ; } buffer[n++]
= b; } return n; } public void Write( int n) { if (n
== 0) { writer.Write(( byte ) ‘0‘ ); return ;
} var i
= buf.Length; for (;
n > 0; n /= 10) buf[--i] = ( byte )((n
% 10) + ‘0‘ ); Write(buf,
i, buf.Length - i); } public void Write( byte []
buffer, int index, int count) { writer.Write(buffer,
index, count); } public void Write( string str) { var buffer
= Encoding.GetBytes(str); writer.Write(buffer,
0, buffer.Length); } public void WriteSpace() { writer.Write(BLANKS,
3, 1); } public void WriteLine() { writer.Write(EOLS,
0, EOLS.Length); } public void Dispose() { if (reader
!= null )
reader.Close(); if (writer
!= null )
writer.Close(); } } } |
此外,IOHelper 类还提供以下方法用于处理字符串:
类似于 C/C++ 语言,这两个方法仅仅把字符串当作字节数组处理,使用 ASCII 码。而不是象 C# 语言中字符串是使用 Unicode 进行编码。
下面是一个使用示例,题目来源请参见“I-Keyboard”这篇随笔。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
namespace Skyiv.Ben.Acm { using System; sealed class Ikeyb { const int MAX
= 90; static int [,]
cost = new int [MAX
+ 1, MAX + 1]; static int [,]
price = new int [MAX
+ 1, MAX + 1]; static int [,]
index = new int [MAX
+ 1, MAX + 1]; static int []
F = new int [MAX]; static byte []
keys = new byte [MAX]; static byte []
letters = new byte [MAX]; static byte []
message1 = IOHelper.GetBytes( "Keypad
#" ); static byte []
message2 = IOHelper.GetBytes( ":
" ); static IOHelper
helper; static void Main() { using (helper
= new IOHelper()) { var runner
= new Ikeyb(); var T
= helper.ReadInt32(); for ( var n
= 1; n <= T; n++) runner.Run(n); } } void Run( int n) { var K
= helper.ReadInt32(); var L
= helper.ReadInt32(); helper.ReadLine(keys); helper.ReadLine(letters); for ( var i
= 0; i < L; i++) F[i] = helper.ReadInt32(); Initialize(K,
L); Compute(K,
L); helper.Write(message1,
0, message1.Length); helper.Write(n); helper.Write(message2,
0, 1); helper.WriteLine(); Output(K,
L); helper.WriteLine(); } void Initialize( int K, int L) { for ( var i
= 0; i <= K; i++) for ( var j
= 1; j <= L; j++) price[i,
j] = int .MaxValue
/ 2; for ( var i
= 1; i <= L; i++) for ( var j
= i; j <= L; j++) cost[i,
j] = cost[i, j - 1] + (j - i + 1) * F[j - 1]; } void Compute( int K, int L) { for ( var i
= 1; i <= K; i++) for ( var j
= i; j <= L; j++) for ( var n
= 1; n <= j - i + 1; n++) { var sum
= price[i - 1, j - n] + cost[j - n + 1, j]; if (sum
<= price[i, j]) { price[i,
j] = sum; index[i,
j] = n; } } } void Output( int K, int L) { if (K
== 0) return ; var n
= index[K--, L]; Output(K,
L - n); helper.Write(keys,
K, 1); helper.Write(message2,
0, message2.Length); helper.Write(letters,
L - n, n); helper.WriteLine(); } } } |
如果给出以下输入:
1 2 5 *# ABCDE 1024 32768 2147483647 987 654321
上述程序将产生以下输出:
Keypad #1: *: ABCD #: E
注意上述输出其实是有问题的,正确的输出应该分为 AB 和 CDE 两组。但是程序本身是没有问题的,而是输入数据有问题。因为原来的题目中限定各个字母出现的频率不能超过 100000。
版权声明:本文为博主http://www.zuiniusn.com原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/u013948187/article/details/47254071