您的位置:首页 > 其它

Codeforces #342 D. Finals in arithmetic 模拟 构造

2016-02-09 21:10 381 查看

题目

题目链接:http://codeforces.com/contest/625/problem/D

题目来源:cf#342

简要题意:给定一个大整数,问是否能由一个无前导零的整数正序,反向相加获得。

题解

这个题非常难处理,需要考虑相当多边边角角的细节。

基本的思路就是从两边向中间去构造。

难点一在于进位,这个可以依靠借和送来解决,分情况。

难点二在于开头无法送位,这个需要特判。

难点三在于判断非法上,边角的条件较多。

总的来说题目易懂,但是解法上需要慎重考虑,好题。

代码

#include <iostream>
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <set>
#include <map>

#define pb push_back
#define mp make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
using namespace std;
typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
LL powmod(LL a,LL b, LL MOD) {LL res=1;a%=MOD;for(;b;b>>=1){if(b&1)res=res*a%MOD;a=a*a%MOD;}return res;}
// head
const int N = 1E5+5;

char s
;
int a
;
char out
;

bool solve(int n) {
for (int l = 0, r = n-1; l <= r; l++, r--) {
// r向前借一位
if (a[l] >= a[r]+10) {
a[r-1]--;
a[r] += 10;
}
// l向后送一位
if (a[l] == a[r]+1) {
a[l]--;
a[l+1] += 10;
}
if (a[l] != a[r]) return false;

// 让高位大,否则11出错
int temp = (a[l]+1)/2;
out[l] = temp + '0';
out[r] = a[l] - temp + '0';
}

// 不加的话100会出错
if (!a[0]) return false;
// 奇数位则中间的必须为偶数
if ((n&1) && (a[n/2]&1)) return false;
for (int i = 0; i < n; i++) {
if (a[i] < 0 || a[i] > 18) return false;
}

out
= '\0';
puts(out);
return true;
}

int main() {
while (gets(s)) {
int n = strlen(s);
for (int i = 0; i < n; i++) {
a[i] = s[i]-'0';
}
if (solve(n)) continue;

// 1打头最高位无法送位,特判
if (s[0] == '1' && n != 1) {
for (int i = 1; i < n; i++) {
a[i-1] = s[i]-'0';
}
a[0] += 10;
if (solve(n-1)) continue;
}

puts("0");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: