【2015-2016 ACM-ICPC, NEERC, Northern Subregional Contest E】【模拟 贪心】Easy Arithmetic 需要补 加减法表达式添加加减号使得数

#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<math.h>
#include<iostream>
#include<string>
#include<set>
#include<map>
#include<vector>
#include<queue>
#include<bitset>
#include<algorithm>
#include<time.h>
using namespace std;
#define MS(x,y) memset(x,y,sizeof(x))
#define MC(x,y) memcpy(x,y,sizeof(x))
#define MP(x,y) make_pair(x,y)
#define ls o<<1
#define rs o<<1|1
typedef long long LL;
typedef unsigned long long UL;
typedef unsigned int UI;
template <class T1,class T2>inline void gmax(T1 &a,T2 b){if(b>a)a=b;}
template <class T1,class T2>inline void gmin(T1 &a,T2 b){if(b<a)a=b;}
const int N=3020,M=0,Z=1e9+7,ms63=1061109567;
int casenum,casei;
char a[N],b[N];
void fre()
{
	freopen("easy.in","r",stdin);
	freopen("easy.out","w",stdout);
}
int main()
{
	fre();
	while(~scanf("%s",a))
	{
		int n=strlen(a);
		int m=0;
		for(int i=0;i<n;)
		{
			b[m++]=a[i];
			if(a[i]=='-')
			{
				b[m++]=a[i+1];
				bool flag=0;
				for(int j=i+2;j<=n;j++)
				{
					if(!isdigit(a[j]))
					{
						i=j;
						break;
					}
					if(flag)b[m++]=a[j];
					else
					{
						if(a[j]>'0')flag=1;
						b[m++]='+';
						b[m++]=a[j];
					}
				}
			}
			else
			{
				for(int j=i+1;j<=n;j++)
				{
					if(!isdigit(a[j]))
					{
						i=j;
						break;
					}
					b[m++]=a[j];
				}
			}
		}
		b[m]=0;
		puts(b);
	}
	return 0;
}
/*
【trick&&吐槽】
判定的顺序把握好!

【题意】
初始给你一个正确的表达式,在这个表达式中——
1,运算符只有'+'和'-',
2,没有前导零,
3,没有连续的运算符
4,最后一个字符必须为数字类型
让你在这个表达式中任意添加'+'和'-',不改变其正确性,
并且使得操作之后的表达式的直接尽可能大。

【类型】
贪心

【分析】
对于加法,我们不改变就好;
对于减法,首位配合减法,之后找到第一个(如果存在)不为'0'的digit,中间的'0'都加起来,后面全部加起来。
i==0时并不一定是加法,然而减法是一定有'-'的。
所以我们先判定是否为'-',是的话是做减法处理。
否则的话一定是'+',就按照加法处理。

有一个细节要注意,就是目标串的长度可能达到2n,也就是数组要开到2000+

【时间复杂度&&优化】
O(n)

【数据】
-50055-6-4-30004560

*/

你可能感兴趣的:(模拟,ACM,codeforces,贪心)