Codeforces 2B. The least round way

原来弄的一发AC原来是假的AC啊,这份代码里面加了一些修正。

特例就在于0的处理,处理不好还会死循环。

思路:要是矩阵中有0,则去找一条ans=0的路径,否则经过此0即可。否则找最短路径。

 

用一个巧妙的方法可以不用特判,用10代替0,则经过0的正常算法得到的结果至少为ans=1,不会引起以下错误:

3

0 0 0

0 0 0

0 0 0

 

#include <iostream>
#include <cstdio>
#include <algorithm>


using namespace std;

unsigned short dp2[1003][1003];
char dp2second[1003][1003];
unsigned short dp5[1003][1003];
char dp5second[1003][1003];

inline unsigned short fenjie2(int tmp) {
	unsigned short res = 0;
	while (tmp&&tmp % 2 == 0) {
		tmp /= 2;
		res++;
	}
	return res;
}

inline unsigned short fenjie5(int tmp) {
	unsigned short res = 0;
	while (tmp&&tmp % 5 == 0) {
		tmp /= 5;
		res++;
	}
	return res;
}

int n;


int main() {
	int havezero = 0;
	int zeroi = -1;
	int zeroj = -1;
	scanf("%d", &n);

	{
		int tmp;
		scanf("%d", &tmp);
		if (tmp == 0) {
			havezero = 1;
			zeroi = 0;
			zeroj = 0;
		}
		dp2[0][0] = fenjie2(tmp);
		dp5[0][0] = fenjie5(tmp);

		for (int j = 1; j < n; j++) {
			scanf("%d", &tmp);
			if (tmp == 0) {
				havezero = 1;
				zeroi = 0;
				zeroj = j;
				tmp = 10;//修正0
			}
			dp2[0][j] = dp2[0][j - 1] + fenjie2(tmp);
			dp5[0][j] = dp5[0][j - 1] + fenjie5(tmp);
			dp2second[0][j] = 'R';
			dp5second[0][j] = 'R';
		}


		for (int i = 1; i < n; i++) {
			for (int j = 0; j < n; j++) {
				scanf("%d", &tmp);
				if (tmp == 0) {
					havezero = 1;
					zeroi = i;
					zeroj = j;
					tmp = 10;//修正
				}
				if (j == 0) {
					dp2[i][0] = dp2[i - 1][0] + fenjie2(tmp);
					dp5[i][0] = dp5[i - 1][0] + fenjie5(tmp);
					dp2second[i][0] = dp5second[i][0] = 'D';
				}
				else {
					if (dp2[i - 1][j] < dp2[i][j - 1]) {
						dp2[i][j] = dp2[i - 1][j] + fenjie2(tmp);
						dp2second[i][j] = 'D';
					}
					else {
						dp2[i][j] = dp2[i][j - 1] + fenjie2(tmp);
						dp2second[i][j] = 'R';
					}

					if (dp5[i - 1][j] < dp5[i][j - 1]) {
						dp5[i][j] = dp5[i - 1][j] + fenjie5(tmp);
						dp5second[i][j] = 'D';
					}
					else {
						dp5[i][j] = dp5[i][j - 1] + fenjie5(tmp);
						dp5second[i][j] = 'R';
					}
				}
			}
		}

		int zero = min(dp2[n - 1][n - 1], dp5[n - 1][n - 1]);
		if (zero == 0 || havezero == 0) {
			char res[2006];
			res[2 * n - 2] = '\0';
			int p = 2 * n - 3;
			if (dp2[n - 1][n - 1] < dp5[n - 1][n - 1]) {
				cout << dp2[n - 1][n - 1] << endl;
				int i = n - 1, j = n - 1;
				while (i || j) {
					res[p--] = dp2second[i][j];
					if (dp2second[i][j] == 'D') {
						i--;
					}
					else
						j--;
				}

			}
			else {
				cout << dp5[n - 1][n - 1] << endl;
				int i = n - 1, j = n - 1;
				while (i || j) {
					res[p--] = dp5second[i][j];
					if (dp5second[i][j] == 'D') {
						i--;
					}
					else
						j--;
				}
			}

			printf("%s\n", res);
		}
		else {
			printf("1\n");
			int needshuchu = 2 * (n - 1);
			needshuchu -= zeroi;
			needshuchu -= n - 1;
			for (int i = 0; i < zeroi; i++) {
				printf("D");
			}
			for (int j = 0; j < n - 1; j++) {
				printf("R");
			}
			for (int i = 0; i < needshuchu; i++) {
				printf("D");
			}
			printf("\n");
		}
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值