标签:
在使用 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