【杭电】[2057]A + B Again

文章字数:929

问题描述

问题分析

做题过程有点变态的一题

首先
这一题是可以用自带的十六进制转化计算几句话就写出来的
不过鉴于以为是大数
所以起初选择了以字符串模拟
(经过测试用时大概比直接写短五分之一)

于是……先放代码

  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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
#include<stdio.h>
#include<string.h>
char s[]= {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
char s1[20],s2[20];
int l1,l2;
int find(char c) {
	int i=0;
	while(s[i]!=c)
		i++;
	return i;
}
int vs() {
	if(l1==l2)
		return strcmp(s1,s2);
	else {
		if(l1>l2)
			return 1;
		else
			return -1;
	}
}
int main() {
//	freopen("input.txt","r",stdin);
//	freopen("output.txt","w",stdout);
	int a[20],b[20],sum[20];
	while(scanf("%s %s",s1,s2)!=EOF) {
		char c1='+',c2='+';
		l1=strlen(s1),l2=strlen(s2);
		if(s1[0]=='+') {
			for(int i=0; i<l1-1; i++) {
				s1[i]=s1[i+1];
			}
			l1--;
		}
		if(s1[0]=='-') {
			c1='-';
			for(int i=0; i<l1-1; i++) {
				s1[i]=s1[i+1];
			}
			l1--;
		}
		if(s2[0]=='+') {
			for(int i=0; i<l2-1; i++) {
				s2[i]=s2[i+1];
			}
			l2--;
		}
		if(s2[0]=='-') {
			c2='-';
			for(int i=0; i<l2-1; i++) {
				s2[i]=s2[i+1];
			}
			l2--;
		}
		int t0=0;
		for(int i=0; i<l1; i++) {
			if(s1[i]=='0')
				t0++;
			else
				break;
		}
		if(t0)
			for(int i=0; i<l1-t0; i++) {
				s1[i]=s1[i+t0];
			}
		l1-=t0;
		t0=0;
		for(int i=0; i<l2; i++) {
			if(s2[i]=='0')
				t0++;
			else
				break;
		}
		if(t0)
			for(int i=0; i<l2-t0; i++) {
				s2[i]=s2[i+t0];
			}
		l2-=t0;
		memset(a,0,sizeof(a));
		memset(b,0,sizeof(b));
		memset(sum,0,sizeof(sum));
		for(int i=0; i<l1; i++)
			a[i]=find(s1[l1-i-1]);
		for(int i=0; i<l2; i++)
			b[i]=find(s2[l2-i-1]);
		if(c1==c2) {
			int lmax;
			if(l1>l2)
				lmax=l1;
			else
				lmax=l2;
			for(int i=0; i<lmax; i++) {
				if(sum[i]+a[i]+b[i]<16)
					sum[i]+=a[i]+b[i];
				else {
					sum[i+1]=1;
					sum[i]+=a[i]+b[i]-16;
				}
			}
			if(sum[lmax]==1)
				lmax++;
			if(lmax==0)
				printf("0\n");
			else {
				if(c1=='-')
					printf("%c",c1);
				bool flag=false;
				for(int i=lmax-1; i>=0; i--) {
					if(s[sum[i]]!='0') {
						printf("%c",s[sum[i]]);
						flag=true;
					} else {
						if(flag)
							printf("%c",s[sum[i]]);
					}
				}
				printf("\n");
			}
		} else {
			int tvs=vs();
			if(tvs==0)
				printf("0\n");
			else {
				int lmax;
				if(tvs>0) {
					if(l1>l2)
						lmax=l1;
					else
						lmax=l2;
					for(int i=0; i<lmax; i++) {
						if(a[i]-b[i]<0) {
							a[i+1]--;
							sum[i]=a[i]+16-b[i];
						} else
							sum[i]=a[i]-b[i];
					}
				} else {
					if(l1>l2)
						lmax=l1;
					else
						lmax=l2;
					for(int i=0; i<lmax; i++) {
						if(b[i]-a[i]<0) {
							b[i+1]--;
							sum[i]=b[i]+16-a[i];
						} else
							sum[i]=b[i]-a[i];
					}
				}
				while(sum[lmax-1]==0&&lmax>0)
					lmax--;
				if(lmax==0)
					printf("0\n");
				else {
					if(tvs>0&&c1=='-')
						printf("%c",c1);
					else if(tvs<0&&c2=='-')
						printf("%c",c2);
					bool flag=false;
					for(int i=lmax-1; i>=0; i--) {
						if(s[sum[i]]!='0') {
							printf("%c",s[sum[i]]);
							flag=true;
						} else {
							if(flag)
								printf("%c",s[sum[i]]);
						}
					}
					printf("\n");
				}
			}
		}
		memset(s1,0,sizeof(s1));
		memset(s2,0,sizeof(s2));
	}
	return 0;
}

大概思路明确之后
其实写起来一点一点还好
不过也是出现了大量的WA
各种细节问题

这个代码的亮点我觉得是以数组保存十六进制数字
然后需要转化时直接依据这个数组就好了

另外我觉得最大的收获是学会了自己进行数据测试
放上一份自己写的生成输入数据代码

 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
#include<stdio.h>
#include <windows.h>
#include <time.h>
char s[]= {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
int main() {
//freopen("input.txt","r",stdin);
	freopen("input.txt","w",stdout);
	srand((unsigned)time(NULL));
	for(int T=0; T<100000; T++) {
		if(rand()%2)
			if(rand()%2)
				printf("+");
			else
				printf("-");
		int l;
		l=rand()%16+1;
		for(int i=0; i<l; i++)
			printf("%c",s[rand()%16]);
		printf(" ");
		if(rand()%2)
			if(rand()%2)
				printf("+");
			else
				printf("-");
		l=rand()%16+1;
		for(int i=0; i<l; i++)
			printf("%c",s[rand()%16]);
		printf("\n");
	}
	return 0;
}

运行之后输入数据会保存成
input.txt

然后在自己的代码里加入

freopen("input.txt","r",stdin);
freopen("output.txt","w",stdout);

然后便可以从input.txt读取数据
输出到output.txt
配合标程输出的数据及文本对比软件(我用的TextDiff)
便可以快速的找出错误了

PS:上传时记得删除测试的那两句
否则会WA
(在下刚开始就是忘了删了)

总之不考虑其它的话
这一题还是收获颇丰的

题目地址:【杭电】[2057]A + B Again

该内容采用 CC BY-NC-SA 4.0 许可协议。

如果对您有帮助或存在意见建议,欢迎在下方评论交流。

加载中...